webpacker 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintignore +3 -0
  3. data/.gitignore +0 -2
  4. data/.travis.yml +3 -3
  5. data/CHANGELOG.md +45 -1
  6. data/Gemfile.lock +144 -0
  7. data/README.md +23 -7
  8. data/docs/deployment.md +3 -6
  9. data/docs/env.md +1 -1
  10. data/docs/misc.md +1 -1
  11. data/docs/props.md +119 -1
  12. data/docs/testing.md +103 -0
  13. data/docs/typescript.md +2 -1
  14. data/docs/webpack-dev-server.md +44 -1
  15. data/docs/webpack.md +37 -1
  16. data/exe/webpack +8 -0
  17. data/exe/webpack-dev-server +8 -0
  18. data/lib/install/config/webpacker.yml +9 -2
  19. data/lib/install/elm.rb +11 -9
  20. data/lib/install/examples/elm/hello_elm.js +4 -3
  21. data/lib/install/examples/vue/hello_vue.js +1 -1
  22. data/lib/install/template.rb +3 -5
  23. data/lib/install/vue.rb +7 -5
  24. data/lib/tasks/webpacker/check_node.rake +6 -3
  25. data/lib/webpacker/configuration.rb +4 -0
  26. data/lib/webpacker/dev_server.rb +19 -5
  27. data/lib/webpacker/dev_server_proxy.rb +1 -1
  28. data/lib/webpacker/dev_server_runner.rb +51 -0
  29. data/lib/webpacker/helper.rb +5 -16
  30. data/lib/webpacker/manifest.rb +8 -8
  31. data/lib/webpacker/runner.rb +22 -0
  32. data/lib/webpacker/version.rb +1 -1
  33. data/lib/webpacker/webpack_runner.rb +15 -0
  34. data/package.json +4 -2
  35. data/package/config.js +19 -2
  36. data/package/environment.js +3 -3
  37. data/package/environments/development.js +15 -11
  38. data/package/environments/production.js +2 -2
  39. data/package/index.js +1 -1
  40. data/package/loaders/file.js +4 -4
  41. data/package/loaders/style.js +2 -2
  42. data/package/loaders/vue.js +2 -2
  43. data/test/configuration_test.rb +5 -0
  44. data/test/manifest_test.rb +10 -2
  45. data/webpacker.gemspec +3 -1
  46. data/yarn.lock +5133 -0
  47. metadata +16 -8
  48. data/lib/install/bin/webpack-dev-server.tt +0 -68
  49. data/lib/install/bin/webpack.tt +0 -27
data/docs/testing.md CHANGED
@@ -1,5 +1,108 @@
1
1
  # Testing
2
2
 
3
+ ## Karma setup for Typescript
4
+
5
+ Webpacker does not setup `Karma` by default, so you've to manually install it along with its dependencies as per your need. Following things marked as optional can be used to fancify the test results (Recommended).
6
+
7
+ ```js
8
+ // package.json
9
+ "scripts": {
10
+ "test": "NODE_ENV=test karma start"
11
+ },
12
+ "dependencies": {
13
+ "typescript": "^2.5.2",
14
+ "ts-loader": "^2.3.7"
15
+ },
16
+ "devDependencies": {
17
+ "karma": "^1.7.1",
18
+ "karma-webpack": "^2.0.4",
19
+ "karma-chrome-launcher": "^2.2.0",
20
+ "karma-jquery": "^0.2.2",
21
+ "karma-jasmine": "^1.1.0",
22
+ "karma-jasmine-jquery": "^0.1.1",
23
+ "jasmine-core": "^2.8.0",
24
+ [optional] "karma-coverage": "^1.1.1",
25
+ [optional] "karma-coverage-istanbul-reporter": "^1.3.0",
26
+ [optional] "karma-spec-reporter": "0.0.31",
27
+ [optional] "istanbul-instrumenter-loader": "^3.0.0",
28
+ }
29
+ ```
30
+
31
+ It is beneficial to use the same webpack configuration file (generated by webpacker) in Karma configuration to avoid redundancy. Following line tells Karma not to write transpiled source files onto filesystem while testing to avoid `Error: EACCES: permission denied, mkdir '/_karma_webpack_' ` error.
32
+
33
+ ```js
34
+ // config/webpack/test.js
35
+ const { environment } = require('@rails/webpacker')
36
+ environment.plugins.get('Manifest').opts.writeToFileEmit = process.env.NODE_ENV !== 'test'
37
+ module.exports = environment
38
+ ```
39
+
40
+ Finally, update `karma.conf.js` to read the same `test.js` file. Then inject a new rule a.k.a. loader in the existing ones (needed only if you have installed `istanbul-instrumenter-loader`) to generate a coverage report under `/coverage` directory. Rest of the things are mandatory (few marked as optional wherever appropriate).
41
+
42
+ ```js
43
+ // karma.conf.js
44
+ const webpackConfig = require('./config/webpack/test.js')
45
+ webpackConfig.module.rules.push({
46
+ test: /\.ts$/,
47
+ enforce: "post",
48
+ loader: "istanbul-instrumenter-loader",
49
+ query: {
50
+ esModules: true
51
+ },
52
+ exclude: ["node_modules", /\.test\.ts$/]
53
+ }) /* optional */
54
+
55
+ module.exports = function(config) {
56
+ config.set({
57
+ basePath: "",
58
+ frameworks: ["jquery-3.2.1", "jasmine-jquery", "jasmine"],
59
+ plugins: [
60
+ "karma-jquery",
61
+ "karma-jasmine-jquery",
62
+ "karma-jasmine",
63
+ "karma-webpack",
64
+ "karma-chrome-launcher",
65
+ "karma-coverage-istanbul-reporter" /* optional */,
66
+ "karma-spec-reporter" /* optional */
67
+ ],
68
+ files: (function () {
69
+ let files = [ "/* add spec files */" ]
70
+ for (let entry in webpackConfig.entry) {
71
+ files.push({
72
+ pattern: webpackConfig.entry[entry],
73
+ watched: true,
74
+ included: false,
75
+ served: true
76
+ })
77
+ }
78
+ return files;
79
+ })(),
80
+ exclude: [],
81
+ webpack: webpackConfig,
82
+ preprocessors: (function() {
83
+ let preprocessors = {
84
+ "/* add spec files */" : ["webpack"]
85
+ }
86
+ for (let entry in webpackConfig.entry) {
87
+ preprocessors[webpackConfig.entry[entry]] = ["webpack"]
88
+ }
89
+ return preprocessors;
90
+ })(),
91
+ mime: { "text/x-typescript": ["ts"] },
92
+ reporters: ["progress", "coverage-istanbul" /* optional */],
93
+ coverageIstanbulReporter: {
94
+ reports: [ 'html', 'lcovonly', 'text-summary' ],
95
+ fixWebpackSourcePaths: true
96
+ } /* optional */,
97
+ port: 9876,
98
+ colors: true,
99
+ logLevel: config.LOG_INFO,
100
+ autoWatch: true,
101
+ browsers: ["Chrome"],
102
+ singleRun: true
103
+ });
104
+ };
105
+ ```
3
106
 
4
107
  ## Lazy compilation
5
108
 
data/docs/typescript.md CHANGED
@@ -28,6 +28,7 @@ yarn add ts-loader typescript @types/react @types/react-dom
28
28
  "exclude": [
29
29
  "**/*.spec.ts",
30
30
  "node_modules",
31
+ "vendor",
31
32
  "public"
32
33
  ],
33
34
  "compileOnSave": false
@@ -55,7 +56,7 @@ yarn add html-loader
55
56
  2. Add html-loader to `config/webpack/environment.js`
56
57
 
57
58
  ```js
58
- environment.loaders.add('html', {
59
+ environment.loaders.set('html', {
59
60
  test: /\.html$/,
60
61
  use: [{
61
62
  loader: 'html-loader',
@@ -17,7 +17,7 @@ Now if you refresh your rails view everything should work as expected.
17
17
  ## HOT module replacement
18
18
 
19
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.
20
+ you can toggle it by setting `dev_server/hmr` option inside `webpacker.yml`.
21
21
 
22
22
  Checkout this guide for more information:
23
23
 
@@ -30,3 +30,46 @@ more information:
30
30
 
31
31
  **Note:** Don't forget to disable `HMR` if you are not running `webpack-dev-server`
32
32
  otherwise you will get not found error for stylesheets.
33
+
34
+
35
+ ## Nginx
36
+
37
+ If you use Nginx in development to proxy requests to your Rails server from
38
+ another domain, like `myapp.dev`, the Webpacker middleware will be able to
39
+ forward requests for "packs" to the Webpack dev server.
40
+
41
+ If you're using `inline` mode behing Nginx, you may also need to provide the
42
+ hostname to Webpack dev server so it can initiate the websocket connection for
43
+ live reloading ([Webpack
44
+ docs](https://webpack.js.org/configuration/dev-server/#devserver-public)).
45
+
46
+ To do so, set the `public` option in `config/webpacker.yml`:
47
+
48
+ ```yaml
49
+ development:
50
+ # ...
51
+ dev_server:
52
+ # ...
53
+ public: myapp.dev
54
+ ```
55
+
56
+ You may also need to add the following location block to your local Nginx server
57
+ configuration for your Rails app.
58
+
59
+ ```
60
+ server {
61
+ listen 80;
62
+ server_name myapp.dev
63
+
64
+ # Proxy webpack dev server websocket requests
65
+ location /sockjs-node {
66
+ proxy_redirect off;
67
+ proxy_http_version 1.1;
68
+ proxy_set_header Upgrade $http_upgrade;
69
+ proxy_set_header Connection "upgrade";
70
+ proxy_pass http://127.0.0.1:3035; # change to match your webpack-dev-server host
71
+ }
72
+
73
+ # ...
74
+ }
75
+ ```
data/docs/webpack.md CHANGED
@@ -8,7 +8,7 @@ production environments in `config/webpack/*.js`. You can configure each individ
8
8
  environment in their respective files or configure them all in the base
9
9
  `config/webpack/environment.js` file.
10
10
 
11
- By default, you shouldn't have to make any changes to `config/webpack/*.js`
11
+ By default, you don't need to make any changes to `config/webpack/*.js`
12
12
  files since it's all standard production-ready configuration. However,
13
13
  if you do need to customize or add a new loader, this is where you would go.
14
14
 
@@ -36,6 +36,14 @@ const customConfig = require('./custom')
36
36
  module.exports = merge(environment.toWebpackConfig(), customConfig)
37
37
  ```
38
38
 
39
+ If you need access to configs within Webpacker's configuration, you can import them like this:
40
+ ```js
41
+ const config = require('@rails/webpacker/package/config');
42
+ const asset_host = require('@rails/webpacker/package/asset_host');
43
+
44
+ console.log(asset_host.publicPathWithHost);
45
+ ```
46
+
39
47
  **Note:** You will have to merge custom config to all env where you want that config
40
48
  to be available. In above case, it will be applied to development environment.
41
49
 
@@ -78,6 +86,34 @@ babelLoader.options.cacheDirectory = false
78
86
  module.exports = environment
79
87
  ```
80
88
 
89
+ ### Overriding Loader Options in Webpack 3+ (for CSS Modules etc.)
90
+
91
+ In Webpack 3+, if you'd like to specify additional or different options for a loader, edit `config/webpack/environment.js` and provide an options object to override. This is similar to the technique shown above, but the following example shows specifically how to apply CSS Modules, which is what you may be looking for:
92
+
93
+ ```javascript
94
+ const { environment } = require('@rails/webpacker')
95
+ const merge = require('webpack-merge')
96
+
97
+ const myCssLoaderOptions = {
98
+ modules: true,
99
+ sourceMap: true,
100
+ localIdentName: '[name]__[local]___[hash:base64:5]'
101
+ }
102
+
103
+ const CSSLoader = environment.loaders.get('style').use.find(el => el.loader === 'css-loader')
104
+
105
+ CSSLoader.options = merge(CSSLoader.options, myCssLoaderOptions)
106
+
107
+ module.exports = environment
108
+ ```
109
+
110
+ See [issue #756](https://github.com/rails/webpacker/issues/756#issuecomment-327148547) for additional discussion of this.
111
+
112
+ For this to work, don't forget to use the `stylesheet_pack_tag`, for example:
113
+
114
+ ```
115
+ <%= stylesheet_pack_tag 'YOUR_PACK_NAME_HERE' %>
116
+ ```
81
117
 
82
118
  ## Plugins
83
119
 
data/exe/webpack ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
4
+ ENV["NODE_ENV"] ||= ENV["RAILS_ENV"]
5
+
6
+ require "webpacker"
7
+ require "webpacker/webpack_runner"
8
+ Webpacker::WebpackRunner.run(ARGV)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
4
+ ENV["NODE_ENV"] ||= ENV["RAILS_ENV"]
5
+
6
+ require "webpacker"
7
+ require "webpacker/dev_server_runner"
8
+ Webpacker::DevServerRunner.run(ARGV)
@@ -10,7 +10,7 @@ default: &default
10
10
  # ['app/assets', 'engine/foo/app/assets']
11
11
  resolved_paths: []
12
12
 
13
- # Reload manifest.json on all requests so we reload latest compiled packs
13
+ # Reload manifest.json on all requests so we reload latest compiled packs
14
14
  cache_manifest: false
15
15
 
16
16
  extensions:
@@ -33,11 +33,18 @@ development:
33
33
  <<: *default
34
34
  compile: true
35
35
 
36
+ # Reference: https://webpack.js.org/configuration/dev-server/
36
37
  dev_server:
38
+ https: false
37
39
  host: localhost
38
40
  port: 3035
41
+ public: localhost:3035
39
42
  hmr: false
40
- https: false
43
+ # Inline should be set to true if using HMR
44
+ inline: true
45
+ overlay: true
46
+ disable_host_check: true
47
+ use_local_ip: false
41
48
 
42
49
  test:
43
50
  <<: *default
data/lib/install/elm.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  require "webpacker/configuration"
2
2
 
3
- puts "Copying elm example entry file to #{Webpacker.config.source_entry_path}"
4
- copy_file "#{__dir__}/examples/elm/Main.elm", "#{Webpacker.config.source_entry_path}/Main.elm"
5
-
6
- puts "Copying elm app file to #{Webpacker.config.source_entry_path}"
3
+ puts "Copying Elm example entry file to #{Webpacker.config.source_entry_path}"
7
4
  copy_file "#{__dir__}/examples/elm/hello_elm.js",
8
- "#{Webpacker.config.source_entry_path}/hello_elm.js"
5
+ "#{Webpacker.config.source_entry_path}/hello_elm.js"
6
+
7
+ puts "Copying Elm app file to #{Webpacker.config.source_path}"
8
+ copy_file "#{__dir__}/examples/elm/Main.elm",
9
+ "#{Webpacker.config.source_path}/Main.elm"
9
10
 
10
- puts "Installing all elm dependencies"
11
+ puts "Installing all Elm dependencies"
11
12
  run "yarn add elm elm-webpack-loader"
12
13
  run "yarn add --dev elm-hot-loader"
13
14
  run "yarn run elm package install -- --yes"
@@ -15,10 +16,11 @@ run "yarn run elm package install -- --yes"
15
16
  puts "Updating Webpack paths to include Elm file extension"
16
17
  insert_into_file Webpacker.config.config_path, " - .elm\n", after: /extensions:\n/
17
18
 
18
- puts "Updating elm source location"
19
- gsub_file "elm-package.json", /\"\.\"\n/, %("#{Webpacker.config.source_entry_path}"\n)
19
+ puts "Updating Elm source location"
20
+ gsub_file "elm-package.json", /\"\.\"\n/,
21
+ %("#{Webpacker.config.source_path.relative_path_from(Rails.root)}"\n)
20
22
 
21
23
  puts "Updating .gitignore to include elm-stuff folder"
22
24
  insert_into_file ".gitignore", "/elm-stuff\n", before: "/node_modules\n"
23
25
 
24
- puts "Webpacker now supports elm 🎉"
26
+ puts "Webpacker now supports Elm 🎉"
@@ -1,7 +1,8 @@
1
- // Run this example by adding <%= javascript_pack_tag "hello_elm" %> to the head of your layout
2
- // file, like app/views/layouts/application.html.erb. It will render "Hello Elm!" within the page.
1
+ // Run this example by adding <%= javascript_pack_tag "hello_elm" %> to the
2
+ // head of your layout file, like app/views/layouts/application.html.erb.
3
+ // It will render "Hello Elm!" within the page.
3
4
 
4
- import Elm from './Main'
5
+ import Elm from '../Main'
5
6
 
6
7
  document.addEventListener('DOMContentLoaded', () => {
7
8
  const target = document.createElement('div')
@@ -6,7 +6,7 @@
6
6
  // All it does is render <div>Hello Vue</div> at the bottom of the page.
7
7
 
8
8
  import Vue from 'vue'
9
- import App from './app.vue'
9
+ import App from '../app.vue'
10
10
 
11
11
  document.addEventListener('DOMContentLoaded', () => {
12
12
  document.body.appendChild(document.createElement('hello'))
@@ -13,10 +13,8 @@ copy_file "#{__dir__}/config/.babelrc", ".babelrc"
13
13
  puts "Creating javascript app source directory"
14
14
  directory "#{__dir__}/javascript", Webpacker.config.source_path
15
15
 
16
- puts "Copying binstubs"
17
- directory "#{__dir__}/bin", "bin"
18
-
19
- chmod "bin", 0755 & ~File.umask, verbose: false
16
+ puts "Installing binstubs"
17
+ run "bundle binstubs webpacker"
20
18
 
21
19
  if File.exists?(".gitignore")
22
20
  append_to_file ".gitignore", <<-EOS
@@ -27,7 +25,7 @@ EOS
27
25
  end
28
26
 
29
27
  puts "Installing all JavaScript dependencies"
30
- run "yarn add @rails/webpacker"
28
+ run "yarn add @rails/webpacker coffeescript@1.12.7"
31
29
 
32
30
  puts "Installing dev server for live reloading"
33
31
  run "yarn add --dev webpack-dev-server"
data/lib/install/vue.rb CHANGED
@@ -1,12 +1,14 @@
1
1
  require "webpacker/configuration"
2
2
 
3
3
  puts "Copying the example entry file to #{Webpacker.config.source_entry_path}"
4
- copy_file "#{__dir__}/examples/vue/hello_vue.js", "#{Webpacker.config.source_entry_path}/hello_vue.js"
4
+ copy_file "#{__dir__}/examples/vue/hello_vue.js",
5
+ "#{Webpacker.config.source_entry_path}/hello_vue.js"
5
6
 
6
- puts "Copying vue app file to #{Webpacker.config.source_entry_path}"
7
- copy_file "#{__dir__}/examples/vue/app.vue", "#{Webpacker.config.source_entry_path}/app.vue"
7
+ puts "Copying Vue app file to #{Webpacker.config.source_entry_path}"
8
+ copy_file "#{__dir__}/examples/vue/app.vue",
9
+ "#{Webpacker.config.source_path}/app.vue"
8
10
 
9
- puts "Installing all vue dependencies"
11
+ puts "Installing all Vue dependencies"
10
12
  run "yarn add vue vue-loader vue-template-compiler"
11
13
 
12
- puts "Webpacker now supports vue.js 🎉"
14
+ puts "Webpacker now supports Vue.js 🎉"
@@ -2,9 +2,12 @@ namespace :webpacker do
2
2
  desc "Verifies if Node.js is installed"
3
3
  task :check_node do
4
4
  begin
5
- node_version = `node -v`
6
- node_version = `nodejs -v` if node_version.blank?
7
- raise Errno::ENOENT if node_version.blank?
5
+ begin
6
+ node_version = `node -v`
7
+ rescue Errno::ENOENT
8
+ node_version = `nodejs -v`
9
+ raise Errno::ENOENT if node_version.blank?
10
+ end
8
11
 
9
12
  pkg_path = Pathname.new("#{__dir__}/../../../package.json").realpath
10
13
  node_requirement = JSON.parse(pkg_path.read)["engines"]["node"]
@@ -45,6 +45,10 @@ class Webpacker::Configuration
45
45
  root_path.join(fetch(:cache_path))
46
46
  end
47
47
 
48
+ def extensions
49
+ fetch(:extensions)
50
+ end
51
+
48
52
  private
49
53
  def fetch(key)
50
54
  data.fetch(key, defaults[key])
@@ -1,4 +1,8 @@
1
1
  class Webpacker::DevServer
2
+ # Configure dev server connection timeout (in seconds), default: 0.01
3
+ # Webpacker.dev_server.connect_timeout = 1
4
+ mattr_accessor(:connect_timeout) { 0.01 }
5
+
2
6
  delegate :config, to: :@webpacker
3
7
 
4
8
  def initialize(webpacker)
@@ -6,14 +10,19 @@ class Webpacker::DevServer
6
10
  end
7
11
 
8
12
  def running?
9
- Socket.tcp(host, port, connect_timeout: 1).close
13
+ Socket.tcp(host, port, connect_timeout: connect_timeout).close
10
14
  true
11
- rescue Errno::ECONNREFUSED, NoMethodError
15
+ rescue
12
16
  false
13
17
  end
14
18
 
15
19
  def hot_module_replacing?
16
- fetch(:hmr)
20
+ case fetch(:hmr)
21
+ when true, "true"
22
+ true
23
+ else
24
+ false
25
+ end
17
26
  end
18
27
 
19
28
  def host
@@ -25,7 +34,12 @@ class Webpacker::DevServer
25
34
  end
26
35
 
27
36
  def https?
28
- fetch(:https)
37
+ case fetch(:https)
38
+ when true, "true"
39
+ true
40
+ else
41
+ false
42
+ end
29
43
  end
30
44
 
31
45
  def protocol
@@ -38,7 +52,7 @@ class Webpacker::DevServer
38
52
 
39
53
  private
40
54
  def fetch(key)
41
- config.dev_server.fetch(key, defaults[key])
55
+ ENV["WEBPACKER_DEV_SERVER_#{key.upcase}"] || config.dev_server.fetch(key, defaults[key])
42
56
  end
43
57
 
44
58
  def defaults