webpacker 2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +21 -21
  4. data/CHANGELOG.md +107 -4
  5. data/Gemfile +3 -1
  6. data/Gemfile.lock +15 -8
  7. data/README.md +137 -937
  8. data/docs/assets.md +106 -0
  9. data/docs/css.md +82 -0
  10. data/docs/deployment.md +39 -0
  11. data/docs/env.md +62 -0
  12. data/docs/es6.md +53 -0
  13. data/docs/folder-structure.md +66 -0
  14. data/docs/misc.md +23 -0
  15. data/docs/props.md +105 -0
  16. data/docs/testing.md +45 -0
  17. data/docs/troubleshooting.md +65 -0
  18. data/docs/typescript.md +115 -0
  19. data/docs/webpack-dev-server.md +32 -0
  20. data/docs/webpack.md +108 -0
  21. data/docs/yarn.md +12 -0
  22. data/lib/install/angular.rb +4 -7
  23. data/lib/install/bin/webpack-dev-server.tt +35 -11
  24. data/lib/install/bin/webpack.tt +3 -4
  25. data/lib/install/config/.babelrc +1 -0
  26. data/lib/install/config/.postcssrc.yml +1 -2
  27. data/lib/install/config/webpack/development.js +2 -31
  28. data/lib/install/config/webpack/environment.js +3 -0
  29. data/lib/install/config/webpack/production.js +2 -34
  30. data/lib/install/config/webpack/test.js +2 -5
  31. data/lib/install/config/webpacker.yml +20 -2
  32. data/lib/install/elm.rb +6 -11
  33. data/lib/install/examples/vue/hello_vue.js +31 -2
  34. data/lib/install/react.rb +2 -5
  35. data/lib/install/template.rb +3 -8
  36. data/lib/install/vue.rb +4 -7
  37. data/lib/tasks/webpacker.rake +1 -1
  38. data/lib/tasks/webpacker/{check_webpack_binstubs.rake → check_binstubs.rake} +3 -2
  39. data/lib/tasks/webpacker/check_node.rake +8 -6
  40. data/lib/tasks/webpacker/check_yarn.rake +2 -2
  41. data/lib/tasks/webpacker/clobber.rake +2 -3
  42. data/lib/tasks/webpacker/compile.rake +16 -18
  43. data/lib/tasks/webpacker/verify_install.rake +5 -5
  44. data/lib/tasks/webpacker/yarn_install.rake +1 -1
  45. data/lib/webpacker.rb +15 -11
  46. data/lib/webpacker/commands.rb +22 -0
  47. data/lib/webpacker/compiler.rb +66 -10
  48. data/lib/webpacker/configuration.rb +54 -38
  49. data/lib/webpacker/dev_server.rb +47 -0
  50. data/lib/webpacker/dev_server_proxy.rb +24 -0
  51. data/lib/webpacker/helper.rb +23 -5
  52. data/lib/webpacker/instance.rb +44 -0
  53. data/lib/webpacker/manifest.rb +58 -34
  54. data/lib/webpacker/railtie.rb +22 -3
  55. data/lib/webpacker/version.rb +2 -1
  56. data/package.json +37 -7
  57. data/package/asset_host.js +21 -0
  58. data/package/config.js +8 -0
  59. data/package/environment.js +95 -0
  60. data/package/environments/development.js +47 -0
  61. data/package/environments/production.js +34 -0
  62. data/package/environments/test.js +3 -0
  63. data/package/index.js +16 -0
  64. data/package/loaders/babel.js +11 -0
  65. data/{lib/install/config/loaders/core → package/loaders}/coffee.js +0 -0
  66. data/{lib/install/config/loaders/installers → package/loaders}/elm.js +4 -5
  67. data/{lib/install/config/loaders/core → package/loaders}/erb.js +0 -0
  68. data/package/loaders/file.js +15 -0
  69. data/package/loaders/style.js +31 -0
  70. data/{lib/install/config/loaders/installers/angular.js → package/loaders/typescript.js} +1 -1
  71. data/package/loaders/vue.js +12 -0
  72. data/test/compiler_test.rb +20 -0
  73. data/test/configuration_test.rb +43 -19
  74. data/test/dev_server_test.rb +24 -0
  75. data/test/helper_test.rb +21 -5
  76. data/test/manifest_test.rb +25 -19
  77. data/test/test_app/public/packs/manifest.json +3 -1
  78. data/test/webpacker_test_helper.rb +40 -0
  79. data/webpacker.gemspec +1 -1
  80. data/yarn.lock +4701 -578
  81. metadata +52 -29
  82. data/lib/install/config/loaders/core/assets.js +0 -12
  83. data/lib/install/config/loaders/core/babel.js +0 -5
  84. data/lib/install/config/loaders/core/sass.js +0 -15
  85. data/lib/install/config/loaders/installers/react.js +0 -5
  86. data/lib/install/config/loaders/installers/vue.js +0 -13
  87. data/lib/install/config/webpack/configuration.js +0 -35
  88. data/lib/install/config/webpack/shared.js +0 -58
  89. data/lib/webpacker/env.rb +0 -23
  90. data/lib/webpacker/file_loader.rb +0 -24
  91. data/test/env_test.rb +0 -14
  92. data/test/webpacker_test.rb +0 -15
data/docs/assets.md ADDED
@@ -0,0 +1,106 @@
1
+ # Assets
2
+
3
+
4
+ Static assets like images and fonts support is enabled out-of-box
5
+ and you can link them into your javascript app code and have them
6
+ compiled automatically.
7
+
8
+
9
+ ## Import from node modules
10
+
11
+ You can also import styles from `node_modules` using the following syntax.
12
+ Please note that your styles will always be extracted into `[pack_name].css`:
13
+
14
+ ```sass
15
+ // app/javascript/styles.sass
16
+ // ~ to tell webpack that this is not a relative import:
17
+
18
+ @import '~@material/animation/mdc-animation'
19
+ @import '~bootstrap/dist/css/bootstrap'
20
+ ```
21
+
22
+ ```js
23
+ // Your main app pack
24
+ // app/javascript/packs/app.js
25
+
26
+ import '../styles'
27
+ ```
28
+
29
+ ```erb
30
+ <%# In your views %>
31
+
32
+ <%= javascript_pack_tag 'app' %>
33
+ <%= stylesheet_pack_tag 'app' %>
34
+ ```
35
+
36
+
37
+ ## Import from sprockets using helpers
38
+
39
+ It's possible to link to assets that have been precompiled by sprockets. Add the `.erb` extension to your javascript file, then you can use Sprockets' asset helpers:
40
+
41
+ ```erb
42
+ <%# app/javascript/my_pack/example.js.erb %>
43
+
44
+ <% helpers = ActionController::Base.helpers %>
45
+ var railsImagePath = "<%= helpers.image_path('rails.png') %>"
46
+ ```
47
+
48
+ This is enabled by the `rails-erb-loader` loader rule in `config/webpack/loaders/erb.js`.
49
+
50
+
51
+ ## Using babel module resolver
52
+
53
+ You can also use [babel-plugin-module-resolver](https://github.com/tleunen/babel-plugin-module-resolver) to reference assets directly from `app/assets/**`
54
+
55
+ ```bash
56
+ yarn add babel-plugin-module-resolver
57
+ ```
58
+
59
+ Specify the plugin in your `.babelrc` with the custom root or alias. Here's an example:
60
+
61
+ ```json
62
+ {
63
+ "plugins": [
64
+ ["module-resolver", {
65
+ "root": ["./app"],
66
+ "alias": {
67
+ "assets": "./assets"
68
+ }
69
+ }]
70
+ ]
71
+ }
72
+ ```
73
+
74
+ And then within your javascript app code:
75
+
76
+ ```js
77
+ // Note: we don't have do any ../../ jazz
78
+
79
+ import FooImage from 'assets/images/foo-image.png'
80
+ import 'assets/stylesheets/bar'
81
+ ```
82
+
83
+
84
+ ## Link in your Rails views
85
+
86
+ You can also link `js/images/styles/fonts` used within your js app in views using
87
+ `asset_pack_path` helper. This helper is useful in cases where you just want to
88
+ create a `<link rel="prefetch">` or `<img />` for an asset.
89
+
90
+ ```yml
91
+ app/javascript:
92
+ - packs
93
+ - hello_react.js
94
+ - styles
95
+ - hello_react.css
96
+ - images
97
+ - calendar.png
98
+ ```
99
+
100
+ ```erb
101
+ <%= asset_pack_path 'hello_react.css' %>
102
+ <%# => "/packs/hello_react.css" %>
103
+
104
+ <img src="<%= asset_pack_path 'images/calendar.png' %>" />
105
+ <% # => <img src="/packs/images/calendar.png" /> %>
106
+ ```
data/docs/css.md ADDED
@@ -0,0 +1,82 @@
1
+ # CSS, SASS and SCSS
2
+
3
+
4
+ Webpacker supports importing css, sass and scss files directly into your javascript files.
5
+
6
+
7
+ ## Import styles into your JS app
8
+
9
+ ```sass
10
+ // app/javascript/hello_react/styles/hello-react.sass
11
+
12
+ .hello-react
13
+ padding: 20px
14
+ font-size: 12px
15
+ ```
16
+
17
+ ```js
18
+ // React component example
19
+ // app/javascripts/packs/hello_react.jsx
20
+
21
+ import React from 'react'
22
+ import helloIcon from '../hello_react/images/icon.png'
23
+ import '../hello_react/styles/hello-react'
24
+
25
+ const Hello = props => (
26
+ <div className="hello-react">
27
+ <img src={helloIcon} alt="hello-icon" />
28
+ <p>Hello {props.name}!</p>
29
+ </div>
30
+ )
31
+ ```
32
+
33
+
34
+ ## Link styles from your Rails views
35
+
36
+ Under the hood webpack uses
37
+ [extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) plugin to extract all the referenced styles within your app and compile it into
38
+ a separate `[pack_name].css` bundle so that in your view you can use the
39
+ `stylesheet_pack_tag` helper.
40
+
41
+ ```erb
42
+ <%= stylesheet_pack_tag 'hello_react' %>
43
+ ```
44
+
45
+
46
+ ## Add bootstrap
47
+
48
+ You can use yarn to add bootstrap or any other modules available on npm:
49
+
50
+ ```bash
51
+ yarn add bootstrap
52
+ ```
53
+
54
+ Import Bootstrap and theme (optional) CSS in your app/javascript/packs/app.js file:
55
+
56
+ ```js
57
+ import 'bootstrap/dist/css/bootstrap'
58
+ import 'bootstrap/dist/css/bootstrap-theme'
59
+ ```
60
+
61
+ Or in your app/javascript/app.sass file:
62
+
63
+ ```sass
64
+ // ~ to tell that this is not a relative import
65
+
66
+ @import '~bootstrap/dist/css/bootstrap'
67
+ @import '~bootstrap/dist/css/bootstrap-theme'
68
+ ```
69
+
70
+
71
+ ## Post-Processing CSS
72
+
73
+ Webpacker out-of-the-box provides CSS post-processing using
74
+ [postcss-loader](https://github.com/postcss/postcss-loader)
75
+ and the installer sets up a standard `.postcssrc.yml`
76
+ file in your app root with standard plugins.
77
+
78
+ ```yml
79
+ plugins:
80
+ postcss-smart-import: {}
81
+ postcss-cssnext: {}
82
+ ```
@@ -0,0 +1,39 @@
1
+ # Deployment
2
+
3
+
4
+ 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
5
+ can manually trigger `bundle exec rails webpacker:compile` during your app deploy.
6
+
7
+ The `javascript_pack_tag` and `stylesheet_pack_tag` helper method will automatically insert the correct HTML tag for compiled pack. Just like the asset pipeline does it.
8
+
9
+ By default the output will look like this in different environments:
10
+
11
+ ```html
12
+ <!-- In development mode -->
13
+ <script src="/packs/calendar.js"></script>
14
+ <link rel="stylesheet" media="screen" href="/packs/calendar.css">
15
+ <!-- In development mode with webpack-dev-server -->
16
+ <script src="http://localhost:8080/calendar.js"></script>
17
+ <link rel="stylesheet" media="screen" href="http://localhost:8080/calendar.css">
18
+ <!-- In production mode -->
19
+ <script src="/packs/calendar-0bd141f6d9360cf4a7f5.js"></script>
20
+ <link rel="stylesheet" media="screen" href="/packs/calendar-dc02976b5f94b507e3b6.css">
21
+ ```
22
+
23
+
24
+ ## Heroku
25
+
26
+ Heroku installs yarn and node by default if you deploy a rails app with
27
+ Webpacker so all you would need to do:
28
+
29
+ ```bash
30
+ heroku create shiny-webpacker-app
31
+ heroku addons:create heroku-postgresql:hobby-dev
32
+ git push heroku master
33
+ ```
34
+
35
+
36
+ ## CDN
37
+
38
+ Webpacker out-of-the-box provides CDN support using your Rails app `config.action_controller.asset_host` setting. If you already have [CDN](http://guides.rubyonrails.org/asset_pipeline.html#cdns) added in your rails app
39
+ you don't need to do anything extra for webpacker, it just works.
data/docs/env.md ADDED
@@ -0,0 +1,62 @@
1
+ # Environment variables
2
+
3
+
4
+ Environment variables are supported out of the box in Webpacker. For example if
5
+ you run the Webpack dev server like so:
6
+ ```
7
+ FOO=hello BAR=world ./bin/webpack-dev-server
8
+ ```
9
+
10
+ You can then reference these variables in your javascript app code with
11
+ `process.env`:
12
+
13
+ ```js
14
+ console.log(process.env.FOO) // Compiles to console.log("hello")
15
+ ```
16
+
17
+ You may want to store configuration in environment variables via `.env` files,
18
+ similar to the [dotenv Ruby gem](https://github.com/bkeepers/dotenv).
19
+
20
+ In development, if you use Foreman or [Invoker](http://invoker.codemancers.com)
21
+ to launch the Webpack server, both of these tools have basic support for a
22
+ `.env` file (Invoker also supports `.env.local`), so no further configuration
23
+ is needed.
24
+
25
+ However, if you run the Webpack server without Foreman/Invoker, or if you
26
+ want more control over what `.env` files to load, you can use the
27
+ [dotenv npm package](https://github.com/motdotla/dotenv). Here is what you could
28
+ do to support a "Ruby-like" dotenv:
29
+
30
+ ```
31
+ yarn add dotenv
32
+ ```
33
+
34
+ ```javascript
35
+ // config/webpack/environment.js
36
+
37
+ ...
38
+ const dotenv = require('dotenv');
39
+
40
+ const dotenvFiles = [
41
+ `.env.${process.env.NODE_ENV}.local`,
42
+ '.env.local',
43
+ `.env.${process.env.NODE_ENV}`,
44
+ '.env'
45
+ ];
46
+ dotenvFiles.forEach((dotenvFile) => {
47
+ dotenv.config({ path: dotenvFile, silent: true });
48
+ });
49
+
50
+ module.exports = {
51
+ ...
52
+ ```
53
+
54
+ **Warning:** using Foreman/Invoker and npm dotenv at the same time can result in
55
+ confusing behavior, in that Foreman/Invoker variables take precedence over
56
+ npm dotenv variables.
57
+
58
+ If you'd like to pass custom variables to the on demand compiler, use `Webpack::Compiler.env` attribute.
59
+
60
+ ```rb
61
+ Webpacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
62
+ ```
data/docs/es6.md ADDED
@@ -0,0 +1,53 @@
1
+ # ES6
2
+
3
+
4
+ ## Babel
5
+
6
+ Webpacker ships with [babel](https://babeljs.io/) - a JavaScript compiler so
7
+ you can use next generation JavaScript, today. The Webpacker installer sets up a
8
+ standard `.babelrc` file in your app root, which will work great in most cases
9
+ because of [babel-env-preset](https://github.com/babel/babel-preset-env).
10
+
11
+ Following ES6/7 features are supported out of the box:
12
+
13
+ * Async/await.
14
+ * Object Rest/Spread Properties.
15
+ * Exponentiation Operator.
16
+ * Dynamic import() - useful for route level code-splitting
17
+ * Class Fields and Static Properties.
18
+
19
+ We have also included [babel polyfill](https://babeljs.io/docs/usage/polyfill/)
20
+ that includes a custom regenerator runtime and core-js.
21
+
22
+ Don't forget to import `babel-polyfill` in your main entry point like so:
23
+
24
+ ```js
25
+ import "babel-polyfill"
26
+ ```
27
+
28
+
29
+ ## Module import() vs require()
30
+
31
+ While you are free to use `require()` and `module.exports`, we encourage you
32
+ to use `import` and `export` instead since it reads and looks much better.
33
+
34
+ ```js
35
+ import Button from 'react-bootstrap/lib/Button'
36
+
37
+ // or
38
+ import { Button } from 'react-bootstrap'
39
+
40
+ class Foo {
41
+ // code...
42
+ }
43
+
44
+ export default Foo
45
+ import Foo from './foo'
46
+ ```
47
+
48
+ You can also use named export and import
49
+
50
+ ```js
51
+ export const foo = () => console.log('hello world')
52
+ import { foo } from './foo'
53
+ ```
@@ -0,0 +1,66 @@
1
+ # Folder Structure
2
+
3
+
4
+ ## Packs a.k.a Webpack entries
5
+
6
+ "Packs" is a special directory made only for Webpack entry files so don't put anything
7
+ here that you don't want to link in your views.
8
+
9
+
10
+ ## Source
11
+
12
+ You can put your app source under `app/javascript` folder or whatever you have configured
13
+ in `config/webpacker.yml`.
14
+
15
+
16
+ ## Example
17
+
18
+ Let's say you're building a calendar app. Your JS app structure could look like this:
19
+
20
+ ```js
21
+ // app/javascript/packs/calendar.js
22
+
23
+ import 'calendar'
24
+ ```
25
+
26
+ ```
27
+ app/javascript/calendar/index.js // gets loaded by import 'calendar'
28
+ app/javascript/calendar/components/grid.jsx
29
+ app/javascript/calendar/styles/grid.sass
30
+ app/javascript/calendar/models/month.js
31
+ ```
32
+
33
+ ```erb
34
+ <%# app/views/layouts/application.html.erb %>
35
+
36
+ <%= javascript_pack_tag 'calendar' %>
37
+ <%= stylesheet_pack_tag 'calendar' %>
38
+ ```
39
+
40
+ But it could also look a million other ways.
41
+
42
+
43
+ ## Namespacing
44
+
45
+ You can also namespace your packs using directories similar to a Rails app.
46
+
47
+ ```
48
+ app/javascript/packs/admin/orders.js
49
+ app/javascript/packs/shop/orders.js
50
+ ```
51
+
52
+ and reference them in your views like this:
53
+
54
+ ```erb
55
+ <%# app/views/admin/orders/index.html.erb %>
56
+
57
+ <%= javascript_pack_tag 'admin/orders' %>
58
+ ```
59
+
60
+ and
61
+
62
+ ```erb
63
+ <%# app/views/shop/orders/index.html.erb %>
64
+
65
+ <%= javascript_pack_tag 'shop/orders' %>
66
+ ```
data/docs/misc.md ADDED
@@ -0,0 +1,23 @@
1
+ # How-Tos
2
+
3
+
4
+ ## Ignoring swap files
5
+
6
+ If you are using vim or emacs and want to ignore certain files you can add `ignore-loader`:
7
+
8
+ ```
9
+ yarn add ignore-loader
10
+ ```
11
+
12
+ and add `ignore-loader` to `config/webpack/environment.js`
13
+
14
+ ```js
15
+ // ignores vue~ swap files
16
+ const { environment } = require('@rails/webpacker')
17
+ environment.loaders.add('ignore', {
18
+ test: /.vue~$/,
19
+ loader: 'ignore-loader'
20
+ })
21
+ ```
22
+
23
+ And now all files with `.vue~` will be ignored by the webpack compiler.
data/docs/props.md ADDED
@@ -0,0 +1,105 @@
1
+ # Props
2
+
3
+
4
+ ## React
5
+
6
+ If you need more advanced React-integration, like server rendering, redux, or react-router, see [shakacode/react_on_rails](https://github.com/shakacode/react_on_rails), [react-rails](https://github.com/reactjs/react-rails), and [webpacker-react](https://github.com/renchap/webpacker-react).
7
+
8
+ If you're not concerned with view helpers to pass props or server rendering, can do it yourself:
9
+
10
+ ```erb
11
+ <%# views/layouts/application.html.erb %>
12
+
13
+ <%= content_tag :div,
14
+ id: "hello-react",
15
+ data: {
16
+ message: 'Hello!',
17
+ name: 'David'
18
+ }.to_json do %>
19
+ <% end %>
20
+ ```
21
+
22
+ ```js
23
+ // app/javascript/packs/hello_react.js
24
+
25
+ const Hello = props => (
26
+ <div className='react-app-wrapper'>
27
+ <img src={clockIcon} alt="clock" />
28
+ <h5 className='hello-react'>
29
+ {props.message} {props.name}!
30
+ </h5>
31
+ </div>
32
+ )
33
+
34
+ // Render component with data
35
+ document.addEventListener('DOMContentLoaded', () => {
36
+ const node = document.getElementById('hello-react')
37
+ const data = JSON.parse(node.getAttribute('data'))
38
+
39
+ ReactDOM.render(<Hello {...data} />, node)
40
+ })
41
+ ```
42
+
43
+
44
+ ## Vue
45
+
46
+ Add the data as attributes in the element you are going to use (or any other element for that matter).
47
+
48
+ ```erb
49
+ <%= content_tag :div,
50
+ id: "hello-vue",
51
+ data: {
52
+ message: "Hello!",
53
+ name: "David"
54
+ }.to_json do %>
55
+ <% end %>
56
+ ```
57
+
58
+ This should produce the following HTML:
59
+
60
+ ```html
61
+ <div id="hello-vue" data="{&quot;message&quot;:&quot;Hello!&quot;,&quot;name&quot;:&quot;David&quot;}"></div>
62
+ ```
63
+
64
+ Now, modify your Vue app to expect the properties.
65
+
66
+ ```html
67
+ <template>
68
+ <div id="app">
69
+ <p>{{test}}{{message}}{{name}}</p>
70
+ </div>
71
+ </template>
72
+
73
+ <script>
74
+ export default {
75
+ // A child component needs to explicitly declare
76
+ // the props it expects to receive using the props option
77
+ // See https://vuejs.org/v2/guide/components.html#Props
78
+ props: ["message","name"],
79
+ data: function () {
80
+ return {
81
+ test: 'This will display: ',
82
+ }
83
+ }
84
+ }
85
+ </script>
86
+
87
+ <style>
88
+ </style>
89
+
90
+ ```
91
+
92
+ ```js
93
+ document.addEventListener('DOMContentLoaded', () => {
94
+ // Get the properties BEFORE the app is instantiated
95
+ const node = document.getElementById('hello-vue')
96
+ const props = JSON.parse(node.getAttribute('data'))
97
+
98
+ // Render component with props
99
+ new Vue({
100
+ render: h => h(App, { props })
101
+ }).$mount('#hello-vue');
102
+ })
103
+ ```
104
+
105
+ You can follow same steps for Angular too.