Skip to content

Commit 34142b1

Browse files
committed
Document the new in-app webpack configuration files and API
1 parent 012a951 commit 34142b1

File tree

1 file changed

+57
-138
lines changed

1 file changed

+57
-138
lines changed

README.md

Lines changed: 57 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,9 @@ precedence over the ones already set in the configuration file.
268268
### Webpack
269269

270270
Webpacker gives you a default set of configuration files for test, development and
271-
production environments. They all live together with the shared
272-
points in `config/webpack/*.js`.
273-
274-
![screen shot 2017-05-23 at 19 56 18](https://cloud.githubusercontent.com/assets/771039/26371229/0983add2-3ff2-11e7-9dc3-d9c2c1094032.png)
271+
production environments in `config/webpack/*.js`. You can configure each individual
272+
environment in their respective files or configure them all in the base
273+
`config/webpack/environment.js` file.
275274

276275
By default, you shouldn't have to make any changes to `config/webpack/*.js`
277276
files since it's all standard production-ready configuration. However,
@@ -280,28 +279,57 @@ if you do need to customize or add a new loader, this is where you would go.
280279

281280
### Loaders
282281

283-
Webpack enables the use of loaders to preprocess files. This allows you to
284-
bundle any static resource way beyond JavaScript. All base loaders
285-
that ship with webpacker are located inside `config/webpack/loaders`.
286-
287-
If you want to add a new loader, for example, to process `json` files via webpack:
282+
You can add additional loaders beyond the base set that webpacker provides by
283+
adding it to your environment. We'll use `json-loader` as an example:
288284

289285
```
290286
yarn add json-loader
291287
```
292288

293-
And create a `json.js` file inside `loaders` directory:
294-
295289
```js
296-
module.exports = {
290+
// config/webpack/environment.js
291+
const { environment } = require('webpacker')
292+
293+
environment.loaders.add('json', {
297294
test: /\.json$/,
298295
use: 'json-loader'
299-
}
296+
})
297+
298+
module.exports = environment
300299
```
301300

302301
Finally add `.json` to the list of extensions in `config/webpacker.yml`. Now if you `import()` any `.json` files inside your javascript
303302
they will be processed using `json-loader`. Voila!
304303

304+
You can also modify the loaders that webpacker pre-configures for you. We'll update
305+
the `babel` loader as an example:
306+
307+
```js
308+
// config/webpack/environment.js
309+
const { environment } = require('webpacker')
310+
311+
// Update an option directly
312+
const babelLoader = environment.loaders.get('babel')
313+
babelLoader.options.cacheDirectory = false
314+
315+
module.exports = environment
316+
```
317+
318+
### Plugins
319+
320+
The process for adding or modifying webpack plugins is the same as the process
321+
for loaders above:
322+
```js
323+
// config/webpack/environment.js
324+
const { environment } = require('webpacker')
325+
326+
// Get a pre-configured plugin
327+
environment.plugins.get("ExtractText") // Is an ExtractTextPlugin instance
328+
// Add an additional plugin of your choosing
329+
environment.plugins.add('Fancy', new MyFancyWebpackPlugin)
330+
331+
module.exports = environment
332+
```
305333

306334
### Paths
307335

@@ -685,41 +713,21 @@ You can follow same steps for Angular too.
685713

686714
The CommonsChunkPlugin is an opt-in feature that creates a separate file (known as a chunk), consisting of common modules shared between multiple entry points. By separating common modules from bundles, the resulting chunked file can be loaded once initially, and stored in the cache for later use. This results in page speed optimizations as the browser can quickly serve the shared code from the cache, rather than being forced to load a larger bundle whenever a new page is visited.
687715

688-
Create a `app-config.js` file inside `config/webpack` and in that file add:
716+
Add the plugins in `config/webpack/environment.js`:
689717

690718
```js
691-
module.exports = {
692-
plugins: [
693-
// Creates a common vendor.js with all shared modules
694-
new webpack.optimize.CommonsChunkPlugin({
695-
name: 'vendor',
696-
minChunks: (module) => {
697-
// this assumes your vendor imports exist in the node_modules directory
698-
return module.context && module.context.indexOf('node_modules') !== -1;
699-
}
700-
}),
701-
// Webpack code chunk - manifest.js
702-
new webpack.optimize.CommonsChunkPlugin({
703-
name: 'manifest',
704-
minChunks: Infinity
705-
})
706-
]
719+
environment.plugins.add('CommonsChunkVendor', new webpack.optimize.CommonsChunkPlugin({
720+
name: 'vendor',
721+
minChunks: (module) => {
722+
// this assumes your vendor imports exist in the node_modules directory
723+
return module.context && module.context.indexOf('node_modules') !== -1;
707724
}
708-
```
725+
}))
709726

710-
You can add this in `shared.js` too but we are doing this to ensure smoother upgrades.
711-
712-
```js
713-
// config/webpack/shared.js
714-
// .... rest of the config
715-
716-
const appConfig = require('./app-config.js')
717-
718-
plugins: appConfig.plugins.concat([
719-
720-
// ...existing plugins
721-
722-
])
727+
environment.plugins.add('CommonsChunkManifest', new webpack.optimize.CommonsChunkPlugin({
728+
name: 'manifest',
729+
minChunks: Infinity
730+
}))
723731
```
724732

725733
Now, add these files to your `layouts/application.html.erb`:
@@ -833,16 +841,7 @@ yarn remove prop-types
833841
}
834842
```
835843

836-
3. Add a new loader `config/webpack/loaders/typescript.js`:
837-
838-
``` js
839-
module.exports = {
840-
test: /.(ts|tsx)$/,
841-
loader: 'ts-loader'
842-
}
843-
```
844-
845-
4. Finally add `.tsx` to the list of extensions in `config/webpacker.yml`
844+
3. Finally add `.tsx` to the list of extensions in `config/webpacker.yml`
846845
and rename your generated `hello_react.js` using react installer
847846
to `hello_react.tsx` and make it valid typescript and now you can use
848847
typescript, JSX with React.
@@ -859,10 +858,10 @@ you would need to follow these steps to add HTML templates support:
859858
yarn add html-loader
860859
```
861860

862-
2. Add html-loader to `config/webpacker/loaders/html.js`
861+
2. Add html-loader to `config/webpack/environment.js`
863862

864863
```js
865-
module.exports = {
864+
environment.loaders.add('html', {
866865
test: /\.html$/,
867866
use: [{
868867
loader: 'html-loader',
@@ -874,7 +873,7 @@ module.exports = {
874873
customAttrAssign: [ /\)?\]?=/ ]
875874
}
876875
}]
877-
}
876+
})
878877
```
879878

880879
3. Add `.html` to `config/webpacker.yml`
@@ -921,48 +920,6 @@ export class AppComponent {
921920

922921
That's all. Voila!
923922

924-
925-
### CSS modules
926-
927-
To enable CSS modules, you would need to update `config/webpack/loaders/sass.js`
928-
file, particularly `css-loader`:
929-
930-
```js
931-
// Add css-modules
932-
933-
{
934-
loader: 'css-loader',
935-
options: {
936-
minimize: env.NODE_ENV === 'production',
937-
modules: true,
938-
localIdentName: '[path][name]__[local]--[hash:base64:5]'
939-
}
940-
}
941-
```
942-
943-
That's all. Now, you can use CSS modules within your JS app:
944-
945-
```js
946-
import React from 'react'
947-
import styles from './styles'
948-
949-
const Hello = props => (
950-
<div className={styles.wrapper}>
951-
<img src={clockIcon} alt="clock" className={styles.img} />
952-
<h5 className={styles.name}>
953-
{props.message} {props.name}!
954-
</h5>
955-
</div>
956-
)
957-
```
958-
959-
960-
### CSS-Next
961-
962-
[css-next](http://cssnext.io/) is supported out-of-box in Webpacker allowing the use of
963-
latest CSS features, today.
964-
965-
966923
### Ignoring swap files
967924

968925
If you are using vim or emacs and want to ignore certain files you can add `ignore-loader`:
@@ -1068,7 +1025,7 @@ yarn add dotenv
10681025
```
10691026

10701027
```javascript
1071-
// config/webpack/shared.js
1028+
// config/webpack/environment.js
10721029
10731030
...
10741031
const dotenv = require('dotenv');
@@ -1097,44 +1054,6 @@ If you'd like to pass custom variables to the compiler, use `Webpack::Compiler.e
10971054
Webpacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
10981055
```
10991056

1100-
## Extending
1101-
1102-
We suggest you don't directly overwrite the provided configuration files
1103-
and extend instead for smoother upgrades. Here is one way to do it:
1104-
1105-
Create a `app-config.js` file inside `config/webpack`, and in that add:
1106-
1107-
```js
1108-
module.exports = {
1109-
production: {
1110-
plugins: [
1111-
// ... Add plugins
1112-
]
1113-
},
1114-
1115-
development: {
1116-
output: {
1117-
// ... Custom output path
1118-
}
1119-
}
1120-
}
1121-
```
1122-
1123-
```js
1124-
// config/webpack/production.js
1125-
1126-
const { plugins } = require('./app-config.js')
1127-
1128-
plugins: appConfig.plugins.concat([
1129-
1130-
// ...existing plugins
1131-
1132-
])
1133-
```
1134-
1135-
But this could be done million other ways.
1136-
1137-
11381057
## Deployment
11391058

11401059
Webpacker hooks up a new `webpacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`. If you are not using sprockets you

0 commit comments

Comments
 (0)