Skip to content

Commit 98eb2b4

Browse files
committed
first commit
0 parents  commit 98eb2b4

File tree

9 files changed

+3772
-0
lines changed

9 files changed

+3772
-0
lines changed

.eslintrc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"rules": {
3+
"keyword-spacing": [ 2 ],
4+
"object-curly-spacing": [ 2, "always"],
5+
"space-before-blocks": [ 2, "always"],
6+
"indent": [ 2, "tab", { "VariableDeclarator": { "var": 2, "let": 2, "const": 3 } } ],
7+
"no-unused-vars": [ 2, { "args": "none" } ],
8+
"space-before-function-paren": [ 2, "never" ],
9+
"semi": [ 2, "always" ],
10+
"no-console": 0,
11+
"mocha/no-exclusive-tests": 2
12+
},
13+
"extends": "eslint:recommended",
14+
"parserOptions": {
15+
"sourceType": "module"
16+
},
17+
"plugins": [
18+
"mocha"
19+
],
20+
"env": {
21+
"node": true,
22+
"es6": true
23+
}
24+
}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
.idea/
3+
*.iml

README.md

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
# hamber-loader
2+
3+
A [Webpack](https://webpack.js.org) loader for [Hamber](https://hamberjs.web.app).
4+
5+
6+
## Usage
7+
8+
Configure inside your `webpack.config.js`:
9+
10+
```javascript
11+
...
12+
resolve: {
13+
// see below for an explanation
14+
alias: {
15+
hamber: path.resolve('node_modules', 'hamber')
16+
},
17+
extensions: ['.mjs', '.js', '.hamber'],
18+
mainFields: ['hamber', 'browser', 'module', 'main']
19+
},
20+
module: {
21+
rules: [
22+
...
23+
{
24+
test: /\.(html|hamber)$/,
25+
exclude: /node_modules/,
26+
use: 'hamber-loader'
27+
}
28+
...
29+
]
30+
}
31+
...
32+
```
33+
34+
Check out the [example project](https://github.com/hamberjs/template-webpack).
35+
36+
### resolve.alias
37+
38+
The [`resolve.alias`](https://webpack.js.org/configuration/resolve/#resolvealias) option is used to make sure that only one copy of the Hamber runtime is bundled in the app, even if you are `npm link`ing in dependencies with their own copy of the `hamber` package. Having multiple copies of the internal scheduler in an app, besides being inefficient, can also cause various problems.
39+
40+
### resolve.mainFields
41+
42+
Webpack's [`resolve.mainFields`](https://webpack.js.org/configuration/resolve/#resolve-mainfields) option determines which fields in package.json are used to resolve identifiers. If you're using Hamber components installed from npm, you should specify this option so that your app can use the original component source code, rather than consuming the already-compiled version (which is less efficient).
43+
44+
### Extracting CSS
45+
46+
If your hamber components contain `<style>` tags, by default the compiler will add JavaScript that injects those styles into the page when the component is rendered. That's not ideal, because it adds weight to your JavaScript, prevents styles from being fetched in parallel with your code, and can even cause CSP violations.
47+
48+
A better option is to extract the CSS into a separate file. Using the `emitCss` option as shown below would cause a virtual CSS file to be emitted for each Hamber component. The resulting file is then imported by the component, thus following the standard Webpack compilation flow. Add [ExtractTextPlugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) to the mix to output the css to a separate file.
49+
50+
```javascript
51+
...
52+
module: {
53+
rules: [
54+
...
55+
{
56+
test: /\.(html|hamber)$/,
57+
exclude: /node_modules/,
58+
use: {
59+
loader: 'hamber-loader',
60+
options: {
61+
emitCss: true,
62+
},
63+
},
64+
},
65+
{
66+
test: /\.css$/,
67+
use: ExtractTextPlugin.extract({
68+
fallback: 'style-loader',
69+
use: 'css-loader',
70+
}),
71+
},
72+
...
73+
]
74+
},
75+
...
76+
plugins: [
77+
new ExtractTextPlugin('styles.css'),
78+
...
79+
]
80+
...
81+
```
82+
83+
Alternatively, if you're handling styles in some other way and just want to prevent the CSS being added to your JavaScript bundle, use `css: false`.
84+
85+
### Source maps
86+
87+
JavaScript source maps are enabled by default, you just have to use an appropriate [webpack devtool](https://webpack.js.org/configuration/devtool/).
88+
89+
To enable CSS source maps, you'll need to use `emitCss` and pass the `sourceMap` option to the `css-loader`. The above config should look like this:
90+
91+
```javascript
92+
module.exports = {
93+
...
94+
devtool: "source-map", // any "source-map"-like devtool is possible
95+
...
96+
module: {
97+
rules: [
98+
...
99+
{
100+
test: /\.(html|hamber)$/,
101+
exclude: /node_modules/,
102+
use: {
103+
loader: 'hamber-loader',
104+
options: {
105+
emitCss: true,
106+
},
107+
},
108+
},
109+
{
110+
test: /\.css$/,
111+
use: ExtractTextPlugin.extract({
112+
fallback: 'style-loader',
113+
use: [{ loader: 'css-loader', options: { sourceMap: true } }],
114+
}),
115+
},
116+
...
117+
]
118+
},
119+
...
120+
plugins: [
121+
new ExtractTextPlugin('styles.css'),
122+
...
123+
]
124+
...
125+
};
126+
```
127+
128+
This should create an additional `styles.css.map` file.
129+
130+
### Hot Reload
131+
132+
Hot reloading is turned off by default, you can turn it on using the `hotReload` option as shown below:
133+
134+
```javascript
135+
...
136+
module: {
137+
rules: [
138+
...
139+
{
140+
test: /\.(html|hamber)$/,
141+
exclude: /node_modules/,
142+
use: {
143+
loader: 'hamber-loader',
144+
options: {
145+
hotReload: true
146+
}
147+
}
148+
}
149+
...
150+
]
151+
}
152+
...
153+
```
154+
155+
#### Hot reload rules and caveats:
156+
157+
- `_rerender` and `_register` are reserved method names, please don't use them in `methods:{...}`
158+
- Turning `dev` mode on (`dev:true`) is **not** necessary.
159+
- Modifying the HTML (template) part of your component will replace and re-render the changes in place. Current local state of the component will also be preserved (this can be turned off per component see [Stop preserving state](#stop-preserving-state)).
160+
- When modifying the `<script>` part of your component, instances will be replaced and re-rendered in place too.
161+
However if your component has lifecycle methods that produce global side-effects, you might need to reload the whole page.
162+
- If you are using `hamber/store`, a full reload is required if you modify `store` properties
163+
164+
165+
Components will **not** be hot reloaded in the following situations:
166+
1. `process.env.NODE_ENV === 'production'`
167+
2. Webpack is minifying code
168+
3. Webpack's `target` is `node` (i.e SSR components)
169+
4. `generate` option has a value of `ssr`
170+
171+
#### Stop preserving state
172+
173+
Sometimes it might be necessary for some components to avoid state preservation on hot reload.
174+
175+
This can be configured on a per-component basis by adding a property `noPreserveState = true` to the component's constructor using the `setup()` method. For example:
176+
```js
177+
export default {
178+
setup(comp){
179+
comp.noPreserveState = true;
180+
},
181+
data(){return {...}},
182+
oncreate(){...}
183+
}
184+
```
185+
186+
Or, on a global basis by adding `{noPreserveState: true}` to `hotOptions`. For example:
187+
```js
188+
{
189+
test: /\.(html|hamber)$/,
190+
exclude: /node_modules/,
191+
use: [
192+
{
193+
loader: 'hamber-loader',
194+
options: {
195+
hotReload: true,
196+
hotOptions: {
197+
noPreserveState: true
198+
}
199+
}
200+
}
201+
]
202+
}
203+
```
204+
205+
**Please Note:** If you are using `hamber/store`, `noPreserveState` has no effect on `store` properties. Neither locally, nor globally.
206+
207+
#### External Dependencies
208+
209+
If you rely on any external dependencies (files required in a preprocessor for example) you might want to watch these files for changes and re-run hamber compile.
210+
211+
Webpack allows [loader dependencies](https://webpack.js.org/contribute/writing-a-loader/#loader-dependencies) to trigger a recompile. hamber-loader exposes this API via `options.externalDependencies`.
212+
For example:
213+
214+
```js
215+
...
216+
const variables = path.resolve('./variables.js');
217+
...
218+
{
219+
test: /\.(html|hamber)$/,
220+
use: [
221+
{
222+
loader: 'hamber-loader',
223+
options: {
224+
externalDependencies: [variables]
225+
}
226+
}
227+
]
228+
}
229+
```
230+
231+
## License
232+
233+
MIT

0 commit comments

Comments
 (0)