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

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 (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
+ ```