webpacker-for-component 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +14 -0
  3. data/.gitignore +6 -0
  4. data/.rubocop.yml +124 -0
  5. data/.travis.yml +22 -0
  6. data/Gemfile +13 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +325 -0
  9. data/Rakefile +12 -0
  10. data/docs/assets.md +106 -0
  11. data/docs/css.md +82 -0
  12. data/docs/deployment.md +39 -0
  13. data/docs/env.md +65 -0
  14. data/docs/es6.md +53 -0
  15. data/docs/folder-structure.md +66 -0
  16. data/docs/misc.md +23 -0
  17. data/docs/props.md +105 -0
  18. data/docs/testing.md +45 -0
  19. data/docs/troubleshooting.md +65 -0
  20. data/docs/typescript.md +116 -0
  21. data/docs/webpack-dev-server.md +32 -0
  22. data/docs/webpack.md +156 -0
  23. data/docs/yarn.md +12 -0
  24. data/lib/install/angular.rb +15 -0
  25. data/lib/install/bin/webpack-dev-server.tt +68 -0
  26. data/lib/install/bin/webpack.tt +30 -0
  27. data/lib/install/config/.babelrc +18 -0
  28. data/lib/install/config/.postcssrc.yml +3 -0
  29. data/lib/install/config/webpack/development.js +3 -0
  30. data/lib/install/config/webpack/environment.js +3 -0
  31. data/lib/install/config/webpack/production.js +3 -0
  32. data/lib/install/config/webpack/test.js +3 -0
  33. data/lib/install/config/webpacker.yml +56 -0
  34. data/lib/install/elm.rb +24 -0
  35. data/lib/install/examples/angular/hello_angular.js +7 -0
  36. data/lib/install/examples/angular/hello_angular/app/app.component.ts +9 -0
  37. data/lib/install/examples/angular/hello_angular/app/app.module.ts +16 -0
  38. data/lib/install/examples/angular/hello_angular/index.ts +8 -0
  39. data/lib/install/examples/angular/hello_angular/polyfills.ts +73 -0
  40. data/lib/install/examples/angular/tsconfig.json +19 -0
  41. data/lib/install/examples/elm/Main.elm +54 -0
  42. data/lib/install/examples/elm/hello_elm.js +11 -0
  43. data/lib/install/examples/react/.babelrc +6 -0
  44. data/lib/install/examples/react/hello_react.jsx +26 -0
  45. data/lib/install/examples/vue/app.vue +22 -0
  46. data/lib/install/examples/vue/hello_vue.js +44 -0
  47. data/lib/install/javascript/packs/application.js +10 -0
  48. data/lib/install/react.rb +28 -0
  49. data/lib/install/template.rb +35 -0
  50. data/lib/install/vue.rb +12 -0
  51. data/lib/tasks/installers.rake +22 -0
  52. data/lib/tasks/webpacker-for-component/check_binstubs.rake +12 -0
  53. data/lib/tasks/webpacker-for-component/check_node.rake +25 -0
  54. data/lib/tasks/webpacker-for-component/check_yarn.rake +24 -0
  55. data/lib/tasks/webpacker-for-component/clobber.rake +16 -0
  56. data/lib/tasks/webpacker-for-component/compile.rake +34 -0
  57. data/lib/tasks/webpacker-for-component/install.rake +13 -0
  58. data/lib/tasks/webpacker-for-component/verify_install.rake +16 -0
  59. data/lib/tasks/webpacker-for-component/yarn_install.rake +6 -0
  60. data/lib/tasks/webpacker.rake +19 -0
  61. data/lib/webpacker-for-component.rb +28 -0
  62. data/lib/webpacker-for-component/commands.rb +23 -0
  63. data/lib/webpacker-for-component/compiler.rb +78 -0
  64. data/lib/webpacker-for-component/configuration.rb +88 -0
  65. data/lib/webpacker-for-component/dev_server.rb +51 -0
  66. data/lib/webpacker-for-component/dev_server_proxy.rb +25 -0
  67. data/lib/webpacker-for-component/helper.rb +65 -0
  68. data/lib/webpacker-for-component/instance.rb +44 -0
  69. data/lib/webpacker-for-component/manifest.rb +79 -0
  70. data/lib/webpacker-for-component/railtie.rb +41 -0
  71. data/lib/webpacker-for-component/version.rb +4 -0
  72. data/package.json +62 -0
  73. data/package/asset_host.js +21 -0
  74. data/package/config.js +8 -0
  75. data/package/environment.js +95 -0
  76. data/package/environments/development.js +46 -0
  77. data/package/environments/production.js +34 -0
  78. data/package/environments/test.js +3 -0
  79. data/package/index.js +16 -0
  80. data/package/loaders/babel.js +11 -0
  81. data/package/loaders/coffee.js +4 -0
  82. data/package/loaders/elm.js +19 -0
  83. data/package/loaders/erb.js +9 -0
  84. data/package/loaders/file.js +15 -0
  85. data/package/loaders/style.js +31 -0
  86. data/package/loaders/typescript.js +4 -0
  87. data/package/loaders/vue.js +12 -0
  88. data/test/command_test.rb +27 -0
  89. data/test/compiler_test.rb +20 -0
  90. data/test/configuration_test.rb +56 -0
  91. data/test/dev_server_test.rb +24 -0
  92. data/test/helper_test.rb +39 -0
  93. data/test/manifest_test.rb +20 -0
  94. data/test/test_app/config/secrets.yml +5 -0
  95. data/test/webpacker_test_helper.rb +40 -0
  96. data/webpacker-for-component.gemspec +23 -0
  97. data/yarn.lock +5162 -0
  98. metadata +111 -7
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.
data/docs/testing.md ADDED
@@ -0,0 +1,45 @@
1
+ # Testing
2
+
3
+
4
+ ## Lazy compilation
5
+
6
+ Webpacker lazily compiles assets in test env so you can write your tests without any extra
7
+ setup and everything will just work out of the box.
8
+
9
+ Here is a sample system test case with hello_react example component:
10
+
11
+ ```js
12
+ // Example react component
13
+
14
+ import React from 'react'
15
+ import ReactDOM from 'react-dom'
16
+ import PropTypes from 'prop-types'
17
+
18
+ const Hello = props => (
19
+ <div>Hello David</div>
20
+ )
21
+
22
+ document.addEventListener('DOMContentLoaded', () => {
23
+ ReactDOM.render(
24
+ <Hello />,
25
+ document.body.appendChild(document.createElement('div')),
26
+ )
27
+ })
28
+ ```
29
+
30
+ ```erb
31
+ <%# views/pages/home.html.erb %>
32
+
33
+ <%= javascript_pack_tag "hello_react" %>
34
+ ```
35
+
36
+ ```rb
37
+ # Tests example react component
38
+ require "application_system_test_case"
39
+ class HomesTest < ApplicationSystemTestCase
40
+ test "can see the hello message" do
41
+ visit root_url
42
+ assert_selector "h5", text: "Hello! David"
43
+ end
44
+ end
45
+ ```
@@ -0,0 +1,65 @@
1
+ # Troubleshooting
2
+
3
+
4
+ ## ENOENT: no such file or directory - node-sass
5
+
6
+ * If you get this error `ENOENT: no such file or directory - node-sass` on Heroku
7
+ or elsewhere during `assets:precompile` or `bundle exec rails webpacker:compile`
8
+ then you would need to rebuild node-sass. It's a bit of a weird error;
9
+ basically, it can't find the `node-sass` binary.
10
+ An easy solution is to create a postinstall hook - `npm rebuild node-sass` in
11
+ `package.json` and that will ensure `node-sass` is rebuilt whenever
12
+ you install any new modules.
13
+
14
+
15
+ ## Can't find hello_react.js in manifest.json
16
+
17
+ * If you get this error `Can't find hello_react.js in manifest.json`
18
+ when loading a view in the browser it's because Webpack is still compiling packs.
19
+ Webpacker uses a `manifest.json` file to keep track of packs in all environments,
20
+ however since this file is generated after packs are compiled by webpack. So,
21
+ if you load a view in browser whilst webpack is compiling you will get this error.
22
+ Therefore, make sure webpack
23
+ (i.e `./bin/webpack-dev-server`) is running and has
24
+ completed the compilation successfully before loading a view.
25
+
26
+
27
+ ## throw er; // Unhandled 'error' event
28
+
29
+ * If you get this error while trying to use Elm, try rebuilding Elm. You can do
30
+ so with a postinstall hook in your `package.json`:
31
+
32
+ ```
33
+ "scripts": {
34
+ "postinstall": "npm rebuild elm"
35
+ }
36
+ ```
37
+
38
+
39
+ ## webpack or webpack-dev-server not found
40
+
41
+ * This could happen if `webpacker:install` step is skipped. Please run `bundle exec rails webpacker:install` to fix the issue.
42
+
43
+ * If you encounter the above error on heroku after upgrading from Rails 4.x to 5.1.x, then the problem might be related to missing `yarn` binstub. Please run following commands to update/add binstubs:
44
+
45
+ ```bash
46
+ bundle config --delete bin
47
+ ./bin/rails app:update:bin # or rails app:update:bin
48
+ ```
49
+
50
+
51
+ ## Running Webpack on Windows
52
+
53
+ If you are running Webpack on Windows, your command shell may not be able to interpret the preferred interpreter
54
+ for the scripts generated in `bin/webpack` and `bin/webpack-dev-server`. Instead you'll want to run the scripts
55
+ manually with Ruby:
56
+
57
+ ```
58
+ C:\path>ruby bin\webpack
59
+ C:\path>ruby bin\webpack-dev-server
60
+ ```
61
+
62
+
63
+ ## Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
64
+
65
+ If you receive this error when running `$ ./bin/webpack-dev-server` ensure your configuration is correct; most likely the path to your "packs" folder is incorrect if you modified from the original "source_path" defined in `config/webpacker.yml`.
@@ -0,0 +1,116 @@
1
+ # Typescript
2
+
3
+
4
+ ## Typescript with React
5
+
6
+ 1. Setup react using webpacker [react installer](#react). Then add required depedencies
7
+ for using typescript with React:
8
+
9
+ ```bash
10
+ yarn add ts-loader typescript @types/react @types/react-dom
11
+ ```
12
+
13
+ 2. Add a `tsconfig.json` to project root:
14
+
15
+ ``` json
16
+ {
17
+ "compilerOptions": {
18
+ "declaration": false,
19
+ "emitDecoratorMetadata": true,
20
+ "experimentalDecorators": true,
21
+ "lib": ["es6", "dom"],
22
+ "module": "es6",
23
+ "moduleResolution": "node",
24
+ "sourceMap": true,
25
+ "jsx": "react",
26
+ "target": "es5"
27
+ },
28
+ "exclude": [
29
+ "**/*.spec.ts",
30
+ "node_modules",
31
+ "vendor"
32
+ "public"
33
+ ],
34
+ "compileOnSave": false
35
+ }
36
+ ```
37
+
38
+ 3. Finally add `.tsx` to the list of extensions in `config/webpacker.yml`
39
+ and rename your generated `hello_react.js` using react installer
40
+ to `hello_react.tsx` and make it valid typescript and now you can use
41
+ typescript, JSX with React.
42
+
43
+
44
+
45
+ ## HTML templates with Typescript and Angular
46
+
47
+ After you have installed angular using `bundle exec rails webpacker:install:angular`
48
+ you would need to follow these steps to add HTML templates support:
49
+
50
+ 1. Use `yarn` to add html-loader
51
+
52
+ ```bash
53
+ yarn add html-loader
54
+ ```
55
+
56
+ 2. Add html-loader to `config/webpack/environment.js`
57
+
58
+ ```js
59
+ environment.loaders.add('html', {
60
+ test: /\.html$/,
61
+ use: [{
62
+ loader: 'html-loader',
63
+ options: {
64
+ minimize: true,
65
+ removeAttributeQuotes: false,
66
+ caseSensitive: true,
67
+ customAttrSurround: [ [/#/, /(?:)/], [/\*/, /(?:)/], [/\[?\(?/, /(?:)/] ],
68
+ customAttrAssign: [ /\)?\]?=/ ]
69
+ }
70
+ }]
71
+ })
72
+ ```
73
+
74
+ 3. Add `.html` to `config/webpacker.yml`
75
+
76
+ ```yml
77
+ extensions:
78
+ - .elm
79
+ - .coffee
80
+ - .html
81
+ ```
82
+
83
+ 4. Setup a custom `d.ts` definition
84
+
85
+ ```ts
86
+ // app/javascript/hello_angular/html.d.ts
87
+
88
+ declare module "*.html" {
89
+ const content: string
90
+ export default content
91
+ }
92
+ ```
93
+
94
+ 5. Add a template.html file relative to `app.component.ts`
95
+
96
+ ```html
97
+ <h1>Hello {{name}}</h1>
98
+ ```
99
+
100
+ 6. Import template into `app.component.ts`
101
+
102
+ ```ts
103
+ import { Component } from '@angular/core'
104
+ import templateString from './template.html'
105
+
106
+ @Component({
107
+ selector: 'hello-angular',
108
+ template: templateString
109
+ })
110
+
111
+ export class AppComponent {
112
+ name = 'Angular!'
113
+ }
114
+ ```
115
+
116
+ That's all. Voila!
@@ -0,0 +1,32 @@
1
+ # Webpack Dev Server
2
+
3
+
4
+ ## HTTPS
5
+
6
+ If you're using the `webpack-dev-server` in development, you can serve your packs over HTTPS
7
+ by setting the `https` option for `webpack-dev-server` to `true` in `config/webpacker.yml`,
8
+ then start the dev server as usual with `./bin/webpack-dev-server`.
9
+
10
+ Please note that the `webpack-dev-server` will use a self-signed certificate,
11
+ so your web browser will display a warning/exception upon accessing the page. If you get
12
+ `https://localhost:3035/sockjs-node/info?t=1503127986584 net::ERR_INSECURE_RESPONSE`
13
+ in your console, simply open the link in your browser and accept the SSL exception.
14
+ Now if you refresh your rails view everything should work as expected.
15
+
16
+
17
+ ## HOT module replacement
18
+
19
+ Webpacker out-of-the-box supports HMR with `webpack-dev-server` and
20
+ you can toggle it by setting `dev_server/hmr` option inside webpacker.yml.
21
+
22
+ Checkout this guide for more information:
23
+
24
+ - https://webpack.js.org/configuration/dev-server/#devserver-hot
25
+
26
+ To support HMR with React you would need to add `react-hot-loader`. Checkout this guide for
27
+ more information:
28
+
29
+ - https://gaearon.github.io/react-hot-loader/getstarted/
30
+
31
+ **Note:** Don't forget to disable `HMR` if you are not running `webpack-dev-server`
32
+ otherwise you will get not found error for stylesheets.
data/docs/webpack.md ADDED
@@ -0,0 +1,156 @@
1
+ # Webpack
2
+
3
+
4
+ ## Configuration
5
+
6
+ Webpacker gives you a default set of configuration files for test, development and
7
+ production environments in `config/webpack/*.js`. You can configure each individual
8
+ environment in their respective files or configure them all in the base
9
+ `config/webpack/environment.js` file.
10
+
11
+ By default, you shouldn't have to make any changes to `config/webpack/*.js`
12
+ files since it's all standard production-ready configuration. However,
13
+ if you do need to customize or add a new loader, this is where you would go.
14
+
15
+ Here is how you can modify webpack configuration:
16
+
17
+ ```js
18
+ // config/webpack/custom.js
19
+ module.exports = {
20
+ resolve: {
21
+ alias: {
22
+ jquery: 'jquery/src/jquery',
23
+ vue: 'vue/dist/vue.js',
24
+ React: 'react',
25
+ ReactDOM: 'react-dom',
26
+ vue_resource: 'vue-resource/dist/vue-resource',
27
+ }
28
+ }
29
+ }
30
+
31
+ // config/webpack/development.js
32
+ const merge = require('webpack-merge')
33
+ const environment = require('./environment')
34
+ const customConfig = require('./custom')
35
+
36
+ module.exports = merge(environment.toWebpackConfig(), customConfig)
37
+ ```
38
+
39
+ **Note:** You will have to merge custom config to all env where you want that config
40
+ to be available. In above case, it will be applied to development environment.
41
+
42
+
43
+ ## Loaders
44
+
45
+ You can add additional loaders beyond the base set that webpacker provides by
46
+ adding it to your environment. We'll use `json-loader` as an example:
47
+
48
+ ```
49
+ yarn add json-loader
50
+ ```
51
+
52
+ ```js
53
+ // config/webpack/environment.js
54
+ const { environment } = require('@rails/webpacker')
55
+
56
+ environment.loaders.set('json', {
57
+ test: /\.json$/,
58
+ use: 'json-loader'
59
+ })
60
+
61
+ module.exports = environment
62
+ ```
63
+
64
+ Finally add `.json` to the list of extensions in `config/webpacker.yml`. Now if you `import()` any `.json` files inside your javascript
65
+ they will be processed using `json-loader`. Voila!
66
+
67
+ You can also modify the loaders that webpacker pre-configures for you. We'll update
68
+ the `babel` loader as an example:
69
+
70
+ ```js
71
+ // config/webpack/environment.js
72
+ const { environment } = require('@rails/webpacker')
73
+
74
+ // Update an option directly
75
+ const babelLoader = environment.loaders.get('babel')
76
+ babelLoader.options.cacheDirectory = false
77
+
78
+ module.exports = environment
79
+ ```
80
+
81
+
82
+ ## Plugins
83
+
84
+ The process for adding or modifying webpack plugins is the same as the process
85
+ for loaders above:
86
+
87
+ ```js
88
+ // config/webpack/environment.js
89
+ const { environment } = require('@rails/webpacker')
90
+ const webpack = require('webpack')
91
+
92
+ // Get a pre-configured plugin
93
+ environment.plugins.get('ExtractText') // Is an ExtractTextPlugin instance
94
+
95
+ // Add an additional plugin of your choosing : ProvidePlugin
96
+ environment.plugins.set(
97
+ 'Provide',
98
+ new webpack.ProvidePlugin({
99
+ $: 'jquery',
100
+ jQuery: 'jquery',
101
+ jquery: 'jquery',
102
+ 'window.Tether': 'tether',
103
+ Popper: ['popper.js', 'default'],
104
+ ActionCable: 'actioncable',
105
+ Vue: 'vue',
106
+ VueResource: 'vue-resource',
107
+ })
108
+ )
109
+
110
+ module.exports = environment
111
+ ```
112
+
113
+
114
+ ### Add common chunks
115
+
116
+ 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.
117
+
118
+ Add the plugins in `config/webpack/environment.js`:
119
+
120
+ ```js
121
+ const webpack = require('webpack')
122
+
123
+ environment.plugins.set(
124
+ 'CommonsChunkVendor',
125
+ new webpack.optimize.CommonsChunkPlugin({
126
+ name: 'vendor',
127
+ minChunks: (module) => {
128
+ // this assumes your vendor imports exist in the node_modules directory
129
+ return module.context && module.context.indexOf('node_modules') !== -1;
130
+ }
131
+ })
132
+ )
133
+
134
+ environment.plugins.set(
135
+ 'CommonsChunkManifest',
136
+ new webpack.optimize.CommonsChunkPlugin({
137
+ name: 'manifest',
138
+ minChunks: Infinity
139
+ })
140
+ )
141
+ ```
142
+
143
+ Now, add these files to your `layouts/application.html.erb`:
144
+
145
+ ```erb
146
+ <%# Head %>
147
+
148
+ <%= javascript_pack_tag "manifest" %>
149
+ <%= javascript_pack_tag "vendor" %>
150
+
151
+ <%# If importing any styles from node_modules in your JS app %>
152
+
153
+ <%= stylesheet_pack_tag "vendor" %>
154
+ ```
155
+
156
+ More detailed guides available here: [Webpack guides](https://webpack.js.org/guides/)