webpacker 2.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +21 -21
- data/CHANGELOG.md +107 -4
- data/Gemfile +3 -1
- data/Gemfile.lock +15 -8
- data/README.md +137 -937
- data/docs/assets.md +106 -0
- data/docs/css.md +82 -0
- data/docs/deployment.md +39 -0
- data/docs/env.md +62 -0
- data/docs/es6.md +53 -0
- data/docs/folder-structure.md +66 -0
- data/docs/misc.md +23 -0
- data/docs/props.md +105 -0
- data/docs/testing.md +45 -0
- data/docs/troubleshooting.md +65 -0
- data/docs/typescript.md +115 -0
- data/docs/webpack-dev-server.md +32 -0
- data/docs/webpack.md +108 -0
- data/docs/yarn.md +12 -0
- data/lib/install/angular.rb +4 -7
- data/lib/install/bin/webpack-dev-server.tt +35 -11
- data/lib/install/bin/webpack.tt +3 -4
- data/lib/install/config/.babelrc +1 -0
- data/lib/install/config/.postcssrc.yml +1 -2
- data/lib/install/config/webpack/development.js +2 -31
- data/lib/install/config/webpack/environment.js +3 -0
- data/lib/install/config/webpack/production.js +2 -34
- data/lib/install/config/webpack/test.js +2 -5
- data/lib/install/config/webpacker.yml +20 -2
- data/lib/install/elm.rb +6 -11
- data/lib/install/examples/vue/hello_vue.js +31 -2
- data/lib/install/react.rb +2 -5
- data/lib/install/template.rb +3 -8
- data/lib/install/vue.rb +4 -7
- data/lib/tasks/webpacker.rake +1 -1
- data/lib/tasks/webpacker/{check_webpack_binstubs.rake → check_binstubs.rake} +3 -2
- data/lib/tasks/webpacker/check_node.rake +8 -6
- data/lib/tasks/webpacker/check_yarn.rake +2 -2
- data/lib/tasks/webpacker/clobber.rake +2 -3
- data/lib/tasks/webpacker/compile.rake +16 -18
- data/lib/tasks/webpacker/verify_install.rake +5 -5
- data/lib/tasks/webpacker/yarn_install.rake +1 -1
- data/lib/webpacker.rb +15 -11
- data/lib/webpacker/commands.rb +22 -0
- data/lib/webpacker/compiler.rb +66 -10
- data/lib/webpacker/configuration.rb +54 -38
- data/lib/webpacker/dev_server.rb +47 -0
- data/lib/webpacker/dev_server_proxy.rb +24 -0
- data/lib/webpacker/helper.rb +23 -5
- data/lib/webpacker/instance.rb +44 -0
- data/lib/webpacker/manifest.rb +58 -34
- data/lib/webpacker/railtie.rb +22 -3
- data/lib/webpacker/version.rb +2 -1
- data/package.json +37 -7
- data/package/asset_host.js +21 -0
- data/package/config.js +8 -0
- data/package/environment.js +95 -0
- data/package/environments/development.js +47 -0
- data/package/environments/production.js +34 -0
- data/package/environments/test.js +3 -0
- data/package/index.js +16 -0
- data/package/loaders/babel.js +11 -0
- data/{lib/install/config/loaders/core → package/loaders}/coffee.js +0 -0
- data/{lib/install/config/loaders/installers → package/loaders}/elm.js +4 -5
- data/{lib/install/config/loaders/core → package/loaders}/erb.js +0 -0
- data/package/loaders/file.js +15 -0
- data/package/loaders/style.js +31 -0
- data/{lib/install/config/loaders/installers/angular.js → package/loaders/typescript.js} +1 -1
- data/package/loaders/vue.js +12 -0
- data/test/compiler_test.rb +20 -0
- data/test/configuration_test.rb +43 -19
- data/test/dev_server_test.rb +24 -0
- data/test/helper_test.rb +21 -5
- data/test/manifest_test.rb +25 -19
- data/test/test_app/public/packs/manifest.json +3 -1
- data/test/webpacker_test_helper.rb +40 -0
- data/webpacker.gemspec +1 -1
- data/yarn.lock +4701 -578
- metadata +52 -29
- data/lib/install/config/loaders/core/assets.js +0 -12
- data/lib/install/config/loaders/core/babel.js +0 -5
- data/lib/install/config/loaders/core/sass.js +0 -15
- data/lib/install/config/loaders/installers/react.js +0 -5
- data/lib/install/config/loaders/installers/vue.js +0 -13
- data/lib/install/config/webpack/configuration.js +0 -35
- data/lib/install/config/webpack/shared.js +0 -58
- data/lib/webpacker/env.rb +0 -23
- data/lib/webpacker/file_loader.rb +0 -24
- data/test/env_test.rb +0 -14
- 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
|
+
```
|
data/docs/deployment.md
ADDED
@@ -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="{"message":"Hello!","name":"David"}"></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.
|