webpacker 6.0.0.beta.2 → 6.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -18
  3. data/Gemfile.lock +1 -1
  4. data/README.md +96 -219
  5. data/docs/assets.md +135 -0
  6. data/docs/cloud9.md +310 -0
  7. data/docs/css.md +303 -0
  8. data/docs/deployment.md +148 -0
  9. data/docs/docker.md +68 -0
  10. data/docs/engines.md +213 -0
  11. data/docs/env.md +68 -0
  12. data/docs/es6.md +72 -0
  13. data/docs/folder-structure.md +66 -0
  14. data/docs/integrations.md +220 -0
  15. data/docs/misc.md +23 -0
  16. data/docs/props.md +187 -0
  17. data/docs/react.md +183 -0
  18. data/docs/target.md +22 -0
  19. data/docs/testing.md +147 -0
  20. data/docs/troubleshooting.md +158 -0
  21. data/docs/typescript.md +190 -0
  22. data/docs/v4-upgrade.md +142 -0
  23. data/docs/webpack-dev-server.md +94 -0
  24. data/docs/webpack.md +315 -0
  25. data/docs/yarn.md +23 -0
  26. data/lib/install/examples/vue3/app.vue +27 -0
  27. data/lib/install/examples/vue3/hello_vue.js +15 -0
  28. data/lib/install/javascript/packs/application.js +1 -3
  29. data/lib/webpacker/compiler.rb +2 -8
  30. data/lib/webpacker/version.rb +1 -1
  31. data/package.json +1 -1
  32. data/package/babel/preset-react.js +62 -0
  33. data/package/babel/preset.js +13 -24
  34. data/package/environments/__tests__/base.js +1 -1
  35. data/package/environments/base.js +19 -19
  36. data/package/environments/production.js +30 -28
  37. data/package/index.js +2 -7
  38. data/package/rules/coffee.js +5 -5
  39. data/package/rules/erb.js +3 -5
  40. data/package/rules/file.js +3 -5
  41. data/package/rules/index.js +17 -9
  42. data/package/rules/less.js +10 -14
  43. data/package/rules/sass.js +9 -13
  44. data/package/rules/svg.js +23 -0
  45. data/package/utils/get_style_rule.js +31 -27
  46. data/package/utils/helpers.js +0 -23
  47. metadata +29 -7
  48. data/6_0_upgrade.md +0 -43
  49. data/package/rules/raw.js +0 -5
  50. data/package/rules/stylus.js +0 -26
@@ -0,0 +1,72 @@
1
+ # ES6
2
+
3
+ ## Babel
4
+
5
+ Webpacker ships with [babel](https://babeljs.io/) - a JavaScript compiler so
6
+ you can use next generation JavaScript, today. The Webpacker installer sets up a
7
+ standard `babel.config.js` file in your app root, which will work great in most cases
8
+ because of [@babel/preset-env](https://github.com/babel/babel/tree/master/packages/babel-preset-env).
9
+
10
+ Following ES6/7 features are supported out of the box:
11
+
12
+ * Async/await.
13
+ * Object Rest/Spread Properties.
14
+ * Exponentiation Operator.
15
+ * Dynamic import() - useful for route level code-splitting
16
+ * Class Fields and Static Properties.
17
+
18
+ We have also included [core-js](https://github.com/zloirock/core-js) to polyfill features in the
19
+ older browsers.
20
+
21
+ Don't forget to add these lines into your main entry point:
22
+
23
+ ```js
24
+ import "core-js/stable";
25
+ import "regenerator-runtime/runtime";
26
+ ```
27
+
28
+ ## Dynamic/Lazy Chunk Loading
29
+
30
+ For this section, you need Webpack and Webpacker 4. Then enable `SplitChunks` as it is explained in [docs/webpack](webpack.md).
31
+
32
+ [Dynamic code splitting](https://webpack.js.org/guides/code-splitting#dynamic-imports) enables you to conditionally request/run only the JS that you need. For example, if your site has a `searchBarComponent` on every page, you can reduce the page overhead by deferring the request for the `searchBarComponent` code until after the page has loaded, until the user has scrolled it into view, or until the user has clicked on an element.
33
+
34
+ ```js
35
+ function loadSearchBarComponent() {
36
+ return import(/* webpackChunkName: "searchBarComponent" */ './pathTo/searchBarComponent')
37
+ }
38
+ ```
39
+
40
+ The comment you see above (`/* webpackChunkName */`) is not arbitrary, it is one of webpacks [magic comments](https://webpack.js.org/api/module-methods/#magic-comments). They can be used to fine-tune `import()` with settings such as `defer` or `prefetch`.
41
+
42
+ **Warning**: You should not attempt to dynamically load anything from your `packs/` folder. Instead, try to make your `pack` scripts a hub from which you dynamically load `non-pack` scripts.
43
+
44
+ - [Docs for using magic comments](https://webpack.js.org/api/module-methods/#magic-comments)
45
+ - [Docs for configuring `splitChunks` in webpacker](/docs/webpack.md#add-splitchunks-webpack-v4).
46
+ - [Docs for using dynamic `import()`](https://webpack.js.org/guides/code-splitting#dynamic-imports).
47
+
48
+ ## Module import vs require()
49
+
50
+ While you are free to use `require()` and `module.exports`, we encourage you
51
+ to use `import` and `export` instead since it reads and looks much better.
52
+
53
+ ```js
54
+ import Button from 'react-bootstrap/lib/Button'
55
+
56
+ // or
57
+ import { Button } from 'react-bootstrap'
58
+
59
+ class Foo {
60
+ // code...
61
+ }
62
+
63
+ export default Foo
64
+ import Foo from './foo'
65
+ ```
66
+
67
+ You can also use named export and import
68
+
69
+ ```js
70
+ export const foo = () => console.log('hello world')
71
+ import { foo } from './foo'
72
+ ```
@@ -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
+ ```
@@ -0,0 +1,220 @@
1
+ # Integrations
2
+
3
+ Webpacker ships with basic out-of-the-box integration for React, Angular, Vue and Elm.
4
+ You can see a list of available commands/tasks by running `bundle exec rails webpacker`:
5
+
6
+ ## React
7
+
8
+ To use Webpacker with [React](https://facebook.github.io/react/), create a
9
+ new Rails 5.1+ app using `--webpack=react` option:
10
+
11
+ ```bash
12
+ # Rails 5.1+
13
+ rails new myapp --webpack=react
14
+ ```
15
+
16
+ (or run `bundle exec rails webpacker:install:react` in an existing Rails app already
17
+ setup with Webpacker).
18
+
19
+ The installer will add all relevant dependencies using Yarn, changes
20
+ to the configuration files, and an example React component to your
21
+ project in `app/javascript/packs` so that you can experiment with React right away.
22
+
23
+
24
+ ## Angular with TypeScript
25
+
26
+ To use Webpacker with [Angular](https://angular.io/), create a
27
+ new Rails 5.1+ app using `--webpack=angular` option:
28
+
29
+ ```bash
30
+ # Rails 5.1+
31
+ rails new myapp --webpack=angular
32
+ ```
33
+
34
+ (or run `bundle exec rails webpacker:install:angular` on a Rails app already
35
+ setup with Webpacker).
36
+
37
+ The installer will add the TypeScript and Angular core libraries using Yarn alongside
38
+ a few changes to the configuration files. An example component written in
39
+ TypeScript will also be added to your project in `app/javascript` so that
40
+ you can experiment with Angular right away.
41
+
42
+ By default, Angular uses a JIT compiler for development environment. This
43
+ compiler is not compatible with restrictive CSP (Content Security
44
+ Policy) environments like Rails 5.2+. You can use Angular AOT compiler
45
+ in development with the [@ngtools/webpack](https://www.npmjs.com/package/@ngtools/webpack#usage) plugin.
46
+
47
+ Alternatively if you're using Rails 5.2+ you can enable `unsafe-eval` rule for your
48
+ development environment. This can be done in the `config/initializers/content_security_policy.rb`
49
+ with the following code:
50
+
51
+ ```ruby
52
+ Rails.application.config.content_security_policy do |policy|
53
+ if Rails.env.development?
54
+ policy.script_src :self, :https, :unsafe_eval
55
+ else
56
+ policy.script_src :self, :https
57
+ end
58
+ end
59
+ ```
60
+
61
+
62
+ ## Vue
63
+
64
+ To use Webpacker with [Vue](https://vuejs.org/), create a
65
+ new Rails 5.1+ app using `--webpack=vue` option:
66
+
67
+ ```bash
68
+ # Rails 5.1+
69
+ rails new myapp --webpack=vue
70
+ ```
71
+ (or run `bundle exec rails webpacker:install:vue` on a Rails app already setup with Webpacker).
72
+
73
+ The installer will add Vue and its required libraries using Yarn alongside
74
+ automatically applying changes needed to the configuration files. An example component will
75
+ be added to your project in `app/javascript` so that you can experiment with Vue right away.
76
+
77
+ If you're using Rails 5.2+ you'll need to enable `unsafe-eval` rule for your development environment.
78
+ This can be done in the `config/initializers/content_security_policy.rb` with the following
79
+ configuration:
80
+
81
+ ```ruby
82
+ Rails.application.config.content_security_policy do |policy|
83
+ if Rails.env.development?
84
+ policy.script_src :self, :https, :unsafe_eval
85
+ else
86
+ policy.script_src :self, :https
87
+ end
88
+ end
89
+ ```
90
+ You can read more about this in the [Vue docs](https://vuejs.org/v2/guide/installation.html#CSP-environments).
91
+
92
+ ### Lazy loading integration
93
+
94
+ See [docs/es6](es6.md) to know more about Webpack and Webpacker configuration.
95
+
96
+ For instance, you can lazy load Vue JS components:
97
+
98
+ Before:
99
+ ```js
100
+ import Vue from 'vue'
101
+ import { VCard } from 'vuetify/lib'
102
+
103
+ Vue.component('VCard', VCard)
104
+ ```
105
+
106
+ After:
107
+ ```js
108
+ import Vue from 'vue'
109
+
110
+ // With destructuring assignment
111
+ Vue.component('VCard', import('vuetify/lib').then(({ VCard }) => VCard)
112
+
113
+ // Or without destructuring assignment
114
+ Vue.component('OtherComponent', () => import('./OtherComponent'))
115
+ ```
116
+
117
+ You can use it in a Single File Component as well:
118
+
119
+ ```html
120
+ <template>
121
+ ...
122
+ </template>
123
+
124
+ <script>
125
+ export default {
126
+ components: {
127
+ OtherComponent: () => import('./OtherComponent')
128
+ }
129
+ }
130
+ </script>
131
+ ```
132
+
133
+ By wrapping the import function into an arrow function, Vue will execute it only when it gets requested, loading the module in that moment.
134
+
135
+ ##### Automatic registration
136
+
137
+ ```js
138
+ /**
139
+ * The following block of code may be used to automatically register your
140
+ * Vue components. It will recursively scan this directory for the Vue
141
+ * components and automatically register them with their "basename".
142
+ *
143
+ * Eg. ./components/OtherComponent.vue -> <other-component></other-component>
144
+ * Eg. ./UI/ButtonComponent.vue -> <button-component></button-component>
145
+ */
146
+
147
+ const files = require.context('./', true, /\.vue$/i)
148
+ files.keys().map(key => {
149
+ const component = key.split('/').pop().split('.')[0]
150
+
151
+ // With Lazy Loading
152
+ Vue.component(component, () => import(`${key}`))
153
+
154
+ // Or without Lazy Loading
155
+ Vue.component(component, files(key).default)
156
+ })
157
+ ```
158
+
159
+ ## Elm
160
+
161
+ To use Webpacker with [Elm](http://elm-lang.org), create a
162
+ new Rails 5.1+ app using `--webpack=elm` option:
163
+
164
+ ```
165
+ # Rails 5.1+
166
+ rails new myapp --webpack=elm
167
+ ```
168
+
169
+ (or run `bundle exec rails webpacker:install:elm` on a Rails app already setup with Webpacker).
170
+
171
+ The Elm library and its core packages will be added via Yarn and Elm.
172
+ An example `Main.elm` app will also be added to your project in `app/javascript`
173
+ so that you can experiment with Elm right away.
174
+
175
+ ## Svelte
176
+
177
+ To use Webpacker with [Svelte](https://svelte.dev), create a
178
+ new Rails 5.1+ app using `--webpack=svelte` option:
179
+
180
+ ```
181
+ # Rails 5.1+
182
+ rails new myapp --webpack=svelte
183
+ ```
184
+
185
+ (or run `bundle exec rails webpacker:install:svelte` on a Rails app already setup with Webpacker).
186
+
187
+ Please play with the [Svelte Tutorial](https://svelte.dev/tutorial/basics) or learn more about its API at https://svelte.dev/docs
188
+
189
+ ## Stimulus
190
+
191
+ To use Webpacker with [Stimulus](http://stimulusjs.org), create a
192
+ new Rails 5.1+ app using `--webpack=stimulus` option:
193
+
194
+ ```
195
+ # Rails 5.1+
196
+ rails new myapp --webpack=stimulus
197
+ ```
198
+
199
+ (or run `bundle exec rails webpacker:install:stimulus` on a Rails app already setup with Webpacker).
200
+
201
+ Please read [The Stimulus Handbook](https://stimulusjs.org/handbook/introduction) or learn more about its source code at https://github.com/stimulusjs/stimulus
202
+
203
+ ## CoffeeScript
204
+
205
+ To add [CoffeeScript](http://coffeescript.org/) support,
206
+ run `bundle exec rails webpacker:install:coffee` on a Rails app already
207
+ setup with Webpacker.
208
+
209
+ An example `hello_coffee.coffee` file will also be added to your project
210
+ in `app/javascript/packs` so that you can experiment with CoffeeScript right away.
211
+
212
+ ## Erb
213
+
214
+ To add [Erb](https://apidock.com/ruby/ERB) support in your JS templates,
215
+ run `bundle exec rails webpacker:install:erb` on a Rails app already
216
+ setup with Webpacker and add extension 'erb' on file `config/webpacker.yml`.
217
+
218
+ An example `hello_erb.js.erb` file will also be added to your project
219
+ in `app/javascript/packs` so that you can experiment with Erb-flavoured
220
+ javascript right away.
@@ -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.append('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.
@@ -0,0 +1,187 @@
1
+ # Props
2
+
3
+ How do you pass props from your view to your JavaScript component? Here you go.
4
+
5
+ ## React
6
+ See [docs/react.md](./react.md#props-hydration-and-server-side-rendering-ssr).
7
+
8
+ ## Vue
9
+
10
+ Add the data as attributes in the element you are going to use (or any other element for that matter).
11
+
12
+ ```erb
13
+ <%= content_tag :div,
14
+ id: "hello-vue",
15
+ data: {
16
+ message: "Hello!",
17
+ name: "David"
18
+ }.to_json do %>
19
+ <% end %>
20
+ ```
21
+
22
+ This should produce the following HTML:
23
+
24
+ ```html
25
+ <div id="hello-vue" data="{&quot;message&quot;:&quot;Hello!&quot;,&quot;name&quot;:&quot;David&quot;}"></div>
26
+ ```
27
+
28
+ Now, modify your Vue app to expect the properties.
29
+
30
+ ```html
31
+ <template>
32
+ <div id="app">
33
+ <p>{{test}}{{message}}{{name}}</p>
34
+ </div>
35
+ </template>
36
+
37
+ <script>
38
+ export default {
39
+ // A child component needs to explicitly declare
40
+ // the props it expects to receive using the props option
41
+ // See https://vuejs.org/v2/guide/components.html#Props
42
+ props: ["message","name"],
43
+ data: function () {
44
+ return {
45
+ test: 'This will display: '
46
+ }
47
+ }
48
+ }
49
+ </script>
50
+
51
+ <style>
52
+ </style>
53
+
54
+ ```
55
+
56
+ ```js
57
+ document.addEventListener('DOMContentLoaded', () => {
58
+ // Get the properties BEFORE the app is instantiated
59
+ const node = document.getElementById('hello-vue')
60
+ const props = JSON.parse(node.getAttribute('data'))
61
+
62
+ // Render component with props
63
+ new Vue({
64
+ render: h => h(App, { props })
65
+ }).$mount('#hello-vue');
66
+ })
67
+ ```
68
+
69
+ You can follow same steps for Angular too.
70
+
71
+
72
+ ## Elm
73
+
74
+ Just like with other implementations, we'll render our data inside a `data`
75
+ attribute:
76
+
77
+ ```erb
78
+ <%= content_tag :div,
79
+ id: "hello-elm",
80
+ data: {
81
+ message: "Hello",
82
+ name: "David"
83
+ }.to_json do %>
84
+ <% end %>
85
+ ```
86
+
87
+ We parse the JSON data and pass it to Elm as flags:
88
+
89
+ ```js
90
+ import Elm from '../Main'
91
+
92
+ document.addEventListener('DOMContentLoaded', () => {
93
+ const node = document.getElementById('hello-elm')
94
+ const data = JSON.parse(node.getAttribute('data'))
95
+ Elm.Main.embed(node, data)
96
+ })
97
+ ```
98
+
99
+ Defining `Flags` as a `type alias`, we instruct Elm to demand flags `message`
100
+ and `name` of type `String` on initialization.
101
+
102
+ Using `programWithFlags` we bring all the pieces together:
103
+
104
+
105
+ ```elm
106
+ module Main exposing (..)
107
+
108
+ import Html exposing (Html, programWithFlags, h1, text)
109
+ import Html.Attributes exposing (style)
110
+
111
+
112
+ -- MODEL
113
+
114
+
115
+ type alias Flags =
116
+ { message : String
117
+ , name : String
118
+ }
119
+
120
+
121
+ type alias Model =
122
+ { message : String
123
+ , name : String
124
+ }
125
+
126
+
127
+ type Msg
128
+ = NoOp
129
+
130
+
131
+
132
+ -- INIT
133
+
134
+
135
+ init : Flags -> ( Model, Cmd Msg )
136
+ init flags =
137
+ let
138
+ { message, name } =
139
+ flags
140
+ in
141
+ ( Model message name, Cmd.none )
142
+
143
+
144
+
145
+ -- UPDATE
146
+
147
+
148
+ update : Msg -> Model -> ( Model, Cmd Msg )
149
+ update msg model =
150
+ case msg of
151
+ NoOp ->
152
+ ( model, Cmd.none )
153
+
154
+
155
+
156
+ -- SUBSCRIPTIONS
157
+
158
+
159
+ subscriptions : Model -> Sub Msg
160
+ subscriptions model =
161
+ Sub.none
162
+
163
+
164
+
165
+ -- VIEW
166
+
167
+
168
+ view : Model -> Html Msg
169
+ view model =
170
+ h1 [ style [ ( "display", "flex" ), ( "justify-content", "center" ) ] ]
171
+ [ text (model.message ++ ", " ++ model.name ++ "!") ]
172
+
173
+
174
+
175
+ -- MAIN
176
+
177
+
178
+ main : Program Flags Model Msg
179
+ main =
180
+ programWithFlags
181
+ { view = view
182
+ , init = init
183
+ , update = update
184
+ , subscriptions = subscriptions
185
+ }
186
+
187
+ ```