5
5
[ ![ Gem] ( https://img.shields.io/gem/v/webpacker.svg )] ( https://github.com/rails/webpacker )
6
6
7
7
Webpacker makes it easy to use the JavaScript pre-processor and bundler
8
- [ Webpack 2 .x.x+] ( https://webpack.js.org/ )
8
+ [ Webpack 3 .x.x+] ( https://webpack.js.org/ )
9
9
to manage application-like JavaScript in Rails. It coexists with the asset pipeline,
10
10
as the primary purpose for Webpack is app-like JavaScript, not images, CSS, or
11
11
even JavaScript Sprinkles (that all continues to live in app/assets).
@@ -90,7 +90,7 @@ in which case you may not even need the asset pipeline. This is mostly relevant
90
90
91
91
## Features
92
92
93
- * [ Webpack 2 ] ( https://webpack.js.org/ )
93
+ * [ Webpack 3.x.x ] ( https://webpack.js.org/ )
94
94
* ES6 with [ babel] ( https://babeljs.io/ )
95
95
* Automatic code splitting using multiple entry points
96
96
* Stylesheets - SASS and CSS
@@ -199,21 +199,6 @@ any changes to the configuration files. An example component will
199
199
also be added to your project in ` app/javascript ` so that you can
200
200
experiment Vue right away.
201
201
202
- #### Using Rails helpers in .vue files
203
-
204
- Rails helpers cannot be used in ` .vue ` files by default. To enable them, change
205
- the extension to ` .vue.erb ` and additionally amend the ` test ` in
206
- ` config/webpack/loaders/vue.js ` to also include ` .vue.erb ` files:
207
-
208
- ``` js
209
- # config/ webpack/ loaders/ vue .js
210
-
211
- module .exports = {
212
- test: / \. vue(\. erb)? $ / ,
213
- ...
214
- }
215
- ```
216
-
217
202
### Elm
218
203
219
204
To use Webpacker with [ Elm] ( http://elm-lang.org ) , create a
@@ -268,10 +253,9 @@ precedence over the ones already set in the configuration file.
268
253
### Webpack
269
254
270
255
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 )
256
+ production environments in ` config/webpack/*.js ` . You can configure each individual
257
+ environment in their respective files or configure them all in the base
258
+ ` config/webpack/environment.js ` file.
275
259
276
260
By default, you shouldn't have to make any changes to ` config/webpack/*.js `
277
261
files since it's all standard production-ready configuration. However,
@@ -280,28 +264,59 @@ if you do need to customize or add a new loader, this is where you would go.
280
264
281
265
### Loaders
282
266
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:
267
+ You can add additional loaders beyond the base set that webpacker provides by
268
+ adding it to your environment. We'll use ` json-loader ` as an example:
288
269
289
270
```
290
271
yarn add json-loader
291
272
```
292
273
293
- And create a ` json.js ` file inside ` loaders ` directory:
294
-
295
274
``` js
296
- module .exports = {
275
+ // config/webpack/environment.js
276
+ const { environment } = require (' @rails/webpacker' )
277
+
278
+ environment .loaders .add (' json' , {
297
279
test: / \. json$ / ,
298
280
use: ' json-loader'
299
- }
281
+ })
282
+
283
+ module .exports = environment
300
284
```
301
285
302
286
Finally add ` .json ` to the list of extensions in ` config/webpacker.yml ` . Now if you ` import() ` any ` .json ` files inside your javascript
303
287
they will be processed using ` json-loader ` . Voila!
304
288
289
+ You can also modify the loaders that webpacker pre-configures for you. We'll update
290
+ the ` babel ` loader as an example:
291
+
292
+ ``` js
293
+ // config/webpack/environment.js
294
+ const { environment } = require (' @rails/webpacker' )
295
+
296
+ // Update an option directly
297
+ const babelLoader = environment .loaders .get (' babel' )
298
+ babelLoader .options .cacheDirectory = false
299
+
300
+ module .exports = environment
301
+ ```
302
+
303
+ ### Plugins
304
+
305
+ The process for adding or modifying webpack plugins is the same as the process
306
+ for loaders above:
307
+
308
+ ``` js
309
+ // config/webpack/environment.js
310
+ const { environment } = require (' @rails/webpacker' )
311
+
312
+ // Get a pre-configured plugin
313
+ environment .plugins .get (' ExtractText' ) // Is an ExtractTextPlugin instance
314
+
315
+ // Add an additional plugin of your choosing
316
+ environment .plugins .add (' Fancy' , new MyFancyWebpackPlugin )
317
+
318
+ module .exports = environment
319
+ ```
305
320
306
321
### Paths
307
322
@@ -409,7 +424,7 @@ Please note that the `webpack-dev-server` will use a self-signed certificate,
409
424
so your web browser will display a warning/exception upon accessing the page. If you get
410
425
` https://localhost:3035/sockjs-node/info?t=1503127986584 net::ERR_INSECURE_RESPONSE`
411
426
in your console, simply open the link in your browser and accept the SSL exception.
412
- Now if you refresh your rails view everything should work as expected.
427
+ Now if you refresh your rails view everything should work as expected.
413
428
414
429
# ## Hot module replacement
415
430
@@ -664,9 +679,7 @@ Now, modify your Vue app to expect the properties.
664
679
665
680
666
681
``` js
667
-
668
682
document .addEventListener (' DOMContentLoaded' , () => {
669
-
670
683
// Get the properties BEFORE the app is instantiated
671
684
const node = document .getElementById (' hello-vue' )
672
685
const props = JSON .parse (node .getAttribute (' data' ))
@@ -685,41 +698,21 @@ You can follow same steps for Angular too.
685
698
686
699
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.
687
700
688
- Create a ` app-config.js ` file inside ` config/webpack ` and in that file add :
701
+ Add the plugins in ` config/webpack/environment.js ` :
689
702
690
703
``` 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
- ]
704
+ environment .plugins .add (' CommonsChunkVendor' , new webpack.optimize.CommonsChunkPlugin ({
705
+ name: ' vendor' ,
706
+ minChunks : (module ) => {
707
+ // this assumes your vendor imports exist in the node_modules directory
708
+ return module .context && module .context .indexOf (' node_modules' ) !== - 1 ;
707
709
}
708
- ```
709
-
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
710
+ }))
721
711
722
- ])
712
+ environment .plugins .add (' CommonsChunkManifest' , new webpack.optimize.CommonsChunkPlugin ({
713
+ name: ' manifest' ,
714
+ minChunks: Infinity
715
+ }))
723
716
```
724
717
725
718
Now, add these files to your ` layouts/application.html.erb ` :
@@ -833,16 +826,7 @@ yarn remove prop-types
833
826
}
834
827
```
835
828
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 `
829
+ 3 . Finally add ` .tsx ` to the list of extensions in ` config/webpacker.yml `
846
830
and rename your generated ` hello_react.js ` using react installer
847
831
to ` hello_react.tsx ` and make it valid typescript and now you can use
848
832
typescript, JSX with React.
@@ -859,10 +843,10 @@ you would need to follow these steps to add HTML templates support:
859
843
yarn add html-loader
860
844
```
861
845
862
- 2 . Add html-loader to ` config/webpacker/loaders/html .js `
846
+ 2 . Add html-loader to ` config/webpack/environment .js `
863
847
864
848
``` js
865
- module . exports = {
849
+ environment . loaders . add ( ' html ' , {
866
850
test: / \. html$ / ,
867
851
use: [{
868
852
loader: ' html-loader' ,
@@ -874,7 +858,7 @@ module.exports = {
874
858
customAttrAssign: [ / \) ? \] ? =/ ]
875
859
}
876
860
}]
877
- }
861
+ })
878
862
```
879
863
880
864
3 . Add ` .html ` to ` config/webpacker.yml `
@@ -921,48 +905,6 @@ export class AppComponent {
921
905
922
906
That's all. Voila!
923
907
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
-
966
908
# ## Ignoring swap files
967
909
968
910
If you are using vim or emacs and want to ignore certain files you can add `ignore-loader` :
@@ -971,16 +913,15 @@ If you are using vim or emacs and want to ignore certain files you can add `igno
971
913
yarn add ignore-loader
972
914
` ` `
973
915
974
- and create a new loader file inside `config/webpack/loaders` :
916
+ and add `ignore- loader` to `config/webpack/environment.js`
975
917
976
918
` ` ` js
977
- // config/webpack/loaders/ignores.js
978
919
// ignores vue~ swap files
979
-
980
- module.exports = {
981
- test: /.vue~$/,
920
+ const { environment } = require('@rails/webpacker')
921
+ environment.loaders.add('ignore', {
922
+ test: /.vue~$/,
982
923
loader: 'ignore-loader'
983
- }
924
+ })
984
925
` ` `
985
926
986
927
And now all files with `.vue~` will be ignored by the webpack compiler.
@@ -1068,7 +1009,7 @@ yarn add dotenv
1068
1009
` ` `
1069
1010
1070
1011
` ` ` javascript
1071
- // config/webpack/shared .js
1012
+ // config/webpack/environment .js
1072
1013
1073
1014
...
1074
1015
const dotenv = require('dotenv');
@@ -1097,44 +1038,6 @@ If you'd like to pass custom variables to the compiler, use `Webpack::Compiler.e
1097
1038
Webpacker ::Compiler .env[' FRONTEND_API_KEY' ] = ' your_secret_key'
1098
1039
```
1099
1040
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
-
1138
1041
## Deployment
1139
1042
1140
1043
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
@@ -1226,13 +1129,6 @@ by adding new paths to `watched_paths` array, much like rails `autoload_paths`:
1226
1129
Webpacker ::Compiler .watched_paths << ' bower_components'
1227
1130
```
1228
1131
1229
- Compiler stores a timestamp under ` tmp/webpacker/ ` directory to keep track of
1230
- changes and you can configure that by overriding compiler ` cache_dir ` :
1231
-
1232
- ``` rb
1233
- Webpacker ::Compiler .cache_dir = " tmp/foo"
1234
- ```
1235
-
1236
1132
## Troubleshooting
1237
1133
1238
1134
##### ENOENT: no such file or directory - node-sass
0 commit comments