webpacker 3.6.0 → 4.0.0.pre.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -3
  3. data/CHANGELOG.md +6 -43
  4. data/Gemfile.lock +48 -58
  5. data/README.md +11 -11
  6. data/Rakefile +2 -1
  7. data/docs/cloud9.md +1 -1
  8. data/docs/css.md +0 -10
  9. data/docs/troubleshooting.md +2 -2
  10. data/lib/install/angular.rb +2 -2
  11. data/lib/install/bin/webpack +1 -1
  12. data/lib/install/bin/webpack-dev-server +1 -1
  13. data/lib/install/config/webpacker.yml +1 -2
  14. data/lib/install/elm.rb +3 -4
  15. data/lib/install/examples/elm/Main.elm +4 -5
  16. data/lib/install/examples/elm/hello_elm.js +2 -6
  17. data/lib/install/examples/vue/hello_vue.js +1 -1
  18. data/lib/install/loaders/elm.js +4 -3
  19. data/lib/install/loaders/vue.js +1 -3
  20. data/lib/install/template.rb +3 -3
  21. data/lib/install/typescript.rb +1 -1
  22. data/lib/install/vue.rb +13 -4
  23. data/lib/tasks/webpacker.rake +0 -1
  24. data/lib/tasks/webpacker/yarn_install.rake +1 -1
  25. data/lib/webpacker.rb +0 -1
  26. data/lib/webpacker/compiler.rb +2 -4
  27. data/lib/webpacker/configuration.rb +3 -13
  28. data/lib/webpacker/dev_server.rb +4 -8
  29. data/lib/webpacker/dev_server_proxy.rb +0 -4
  30. data/lib/webpacker/dev_server_runner.rb +7 -15
  31. data/lib/webpacker/env.rb +1 -1
  32. data/lib/webpacker/helper.rb +0 -10
  33. data/lib/webpacker/instance.rb +2 -6
  34. data/lib/webpacker/railtie.rb +1 -2
  35. data/lib/webpacker/version.rb +1 -1
  36. data/package.json +16 -16
  37. data/package/__tests__/config.js +1 -17
  38. data/package/__tests__/production.js +1 -3
  39. data/package/__tests__/staging.js +1 -3
  40. data/package/__tests__/test.js +1 -3
  41. data/package/config.js +1 -9
  42. data/package/dev_server.js +1 -1
  43. data/package/env.js +2 -2
  44. data/package/environments/base.js +22 -5
  45. data/package/environments/development.js +2 -0
  46. data/package/environments/production.js +26 -36
  47. data/package/utils/__tests__/deep_assign.js +6 -27
  48. data/package/utils/deep_assign.js +1 -1
  49. data/package/utils/get_style_rule.js +26 -37
  50. data/test/configuration_test.rb +22 -46
  51. data/test/helper_test.rb +0 -6
  52. data/test/test_app/config/webpacker.yml +0 -1
  53. data/test/test_helper.rb +0 -2
  54. data/webpacker.gemspec +0 -5
  55. data/yarn.lock +2199 -998
  56. metadata +6 -11
  57. data/lib/tasks/webpacker/info.rake +0 -19
  58. data/test/webpacker_test.rb +0 -13
@@ -1,30 +1,14 @@
1
1
  /* global test expect, describe */
2
2
 
3
- const { chdirCwd, chdirTestApp } = require('../utils/helpers')
3
+ const { chdirTestApp, chdirCwd } = require('../utils/helpers')
4
4
 
5
5
  chdirTestApp()
6
6
 
7
7
  const config = require('../config')
8
8
 
9
9
  describe('Config', () => {
10
- beforeEach(() => jest.resetModules())
11
10
  afterAll(chdirCwd)
12
11
 
13
- test('public path', () => {
14
- process.env.RAILS_ENV = 'development'
15
- delete process.env.RAILS_RELATIVE_URL_ROOT
16
- const config = require('../config')
17
- expect(config.publicPath).toEqual('/packs/')
18
- })
19
-
20
- // also tests removal of extra slashes
21
- test('public path with relative root', () => {
22
- process.env.RAILS_ENV = 'development'
23
- process.env.RAILS_RELATIVE_URL_ROOT = '/foo'
24
- const config = require('../config')
25
- expect(config.publicPath).toEqual('/foo/packs/')
26
- })
27
-
28
12
  test('should return extensions as listed in app config', () => {
29
13
  expect(config.extensions).toEqual([
30
14
  '.js',
@@ -13,11 +13,9 @@ describe('Production environment', () => {
13
13
 
14
14
  test('should use production config and environment', () => {
15
15
  process.env.RAILS_ENV = 'production'
16
- process.env.NODE_ENV = 'production'
17
-
18
16
  const { environment } = require('../index')
17
+
19
18
  const config = environment.toWebpackConfig()
20
-
21
19
  expect(config.output.path).toEqual(resolve('public', 'packs'))
22
20
  expect(config.output.publicPath).toEqual('/packs/')
23
21
  expect(config).toMatchObject({
@@ -13,11 +13,9 @@ describe('Custom environment', () => {
13
13
 
14
14
  test('should use staging config and production environment', () => {
15
15
  process.env.RAILS_ENV = 'staging'
16
- delete process.env.NODE_ENV
17
-
18
16
  const { environment } = require('../index')
17
+
19
18
  const config = environment.toWebpackConfig()
20
-
21
19
  expect(config.output.path).toEqual(resolve('public', 'packs-staging'))
22
20
  expect(config.output.publicPath).toEqual('/packs-staging/')
23
21
  expect(config).toMatchObject({
@@ -13,11 +13,9 @@ describe('Test environment', () => {
13
13
 
14
14
  test('should use test config and production environment', () => {
15
15
  process.env.RAILS_ENV = 'test'
16
- process.env.NODE_ENV = 'test'
17
-
18
16
  const { environment } = require('../index')
17
+
19
18
  const config = environment.toWebpackConfig()
20
-
21
19
  expect(config.output.path).toEqual(resolve('public', 'packs-test'))
22
20
  expect(config.output.publicPath).toEqual('/packs-test/')
23
21
  })
@@ -20,14 +20,6 @@ if (isArray(app.extensions) && app.extensions.length) delete defaults.extensions
20
20
 
21
21
  const config = deepMerge(defaults, app)
22
22
  config.outputPath = resolve('public', config.public_output_path)
23
-
24
- let publicPath = `/${config.public_output_path}/`
25
- // Add prefix to publicPath.
26
- if (process.env.RAILS_RELATIVE_URL_ROOT) {
27
- publicPath = `/${process.env.RAILS_RELATIVE_URL_ROOT}${publicPath}`
28
- }
29
-
30
- // Remove extra slashes.
31
- config.publicPath = publicPath.replace(/(^\/|[^:]\/)\/+/g, '$1')
23
+ config.publicPath = `/${config.public_output_path}/`.replace(/([^:]\/)\/+/g, '$1')
32
24
 
33
25
  module.exports = config
@@ -11,7 +11,7 @@ const devServerConfig = config.dev_server
11
11
  if (devServerConfig) {
12
12
  Object.keys(devServerConfig).forEach((key) => {
13
13
  const envValue = fetch(`WEBPACKER_DEV_SERVER_${key.toUpperCase().replace(/_/g, '')}`)
14
- if (envValue !== undefined) devServerConfig[key] = envValue
14
+ if (envValue) devServerConfig[key] = envValue
15
15
  })
16
16
  }
17
17
 
@@ -2,7 +2,7 @@ const { resolve } = require('path')
2
2
  const { safeLoad } = require('js-yaml')
3
3
  const { readFileSync } = require('fs')
4
4
 
5
- const NODE_ENVIRONMENTS = ['development', 'production', 'test']
5
+ const NODE_ENVIRONMENTS = ['development', 'production']
6
6
  const DEFAULT = 'production'
7
7
  const configPath = resolve('config', 'webpacker.yml')
8
8
 
@@ -11,7 +11,7 @@ const nodeEnv = process.env.NODE_ENV
11
11
 
12
12
  const config = safeLoad(readFileSync(configPath), 'utf8')
13
13
  const availableEnvironments = Object.keys(config).join('|')
14
- const regex = new RegExp(`^(${availableEnvironments})$`, 'g')
14
+ const regex = new RegExp(availableEnvironments, 'g')
15
15
 
16
16
  module.exports = {
17
17
  railsEnv: railsEnv && railsEnv.match(regex) ? railsEnv : DEFAULT,
@@ -8,8 +8,8 @@ const { sync } = require('glob')
8
8
  const extname = require('path-complete-extname')
9
9
 
10
10
  const webpack = require('webpack')
11
- const ExtractTextPlugin = require('extract-text-webpack-plugin')
12
- const ManifestPlugin = require('webpack-manifest-plugin')
11
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
12
+ const WebpackAssetsManifest = require('webpack-assets-manifest')
13
13
  const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
14
14
 
15
15
  const { ConfigList, ConfigObject } = require('../config_types')
@@ -24,10 +24,25 @@ const getLoaderList = () => {
24
24
 
25
25
  const getPluginList = () => {
26
26
  const result = new ConfigList()
27
- result.append('Environment', new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env))))
27
+ result.append(
28
+ 'Environment',
29
+ new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env)))
30
+ )
28
31
  result.append('CaseSensitivePaths', new CaseSensitivePathsPlugin())
29
- result.append('ExtractText', new ExtractTextPlugin('[name]-[contenthash].css'))
30
- result.append('Manifest', new ManifestPlugin({ publicPath: config.publicPath, writeToFileEmit: true }))
32
+ result.append(
33
+ 'ExtractText',
34
+ new MiniCssExtractPlugin({
35
+ filename: '[name]-[contenthash:8].css',
36
+ chunkFilename: '[name]-[contenthash:8].chunk.css'
37
+ })
38
+ )
39
+ result.append(
40
+ 'Manifest',
41
+ new WebpackAssetsManifest({
42
+ writeToDisk: true,
43
+ publicPath: true
44
+ })
45
+ )
31
46
  return result
32
47
  }
33
48
 
@@ -61,9 +76,11 @@ const getModulePaths = () => {
61
76
 
62
77
  const getBaseConfig = () =>
63
78
  new ConfigObject({
79
+ mode: 'production',
64
80
  output: {
65
81
  filename: '[name]-[chunkhash].js',
66
82
  chunkFilename: '[name]-[chunkhash].chunk.js',
83
+ hotUpdateChunkFilename: '[id]-[hash].hot-update.js',
67
84
  path: config.outputPath,
68
85
  publicPath: config.publicPath
69
86
  },
@@ -14,6 +14,8 @@ module.exports = class extends Base {
14
14
  }
15
15
 
16
16
  this.config.merge({
17
+ mode: 'development',
18
+ cache: true,
17
19
  devtool: 'cheap-module-source-map',
18
20
  output: {
19
21
  pathinfo: true
@@ -1,45 +1,11 @@
1
- const webpack = require('webpack')
2
- const CompressionPlugin = require('compression-webpack-plugin')
3
1
  const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
4
- const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
2
+ const CompressionPlugin = require('compression-webpack-plugin')
5
3
  const Base = require('./base')
6
4
 
7
5
  module.exports = class extends Base {
8
6
  constructor() {
9
7
  super()
10
8
 
11
- this.plugins.append('ModuleConcatenation', new webpack.optimize.ModuleConcatenationPlugin())
12
- this.plugins.append('OptimizeCSSAssets', new OptimizeCSSAssetsPlugin())
13
-
14
- this.plugins.append(
15
- 'UglifyJs',
16
- new UglifyJsPlugin({
17
- parallel: true,
18
- cache: true,
19
- sourceMap: true,
20
- uglifyOptions: {
21
- parse: {
22
- // Let uglify-js parse ecma 8 code but always output
23
- // ES5 compliant code for older browsers
24
- ecma: 8
25
- },
26
- compress: {
27
- ecma: 5,
28
- warnings: false,
29
- comparisons: false
30
- },
31
- mangle: {
32
- safari10: true
33
- },
34
- output: {
35
- ecma: 5,
36
- comments: false,
37
- ascii_only: true
38
- }
39
- }
40
- })
41
- )
42
-
43
9
  this.plugins.append(
44
10
  'Compression',
45
11
  new CompressionPlugin({
@@ -51,7 +17,31 @@ module.exports = class extends Base {
51
17
 
52
18
  this.config.merge({
53
19
  devtool: 'nosources-source-map',
54
- stats: 'normal'
20
+ stats: 'normal',
21
+ bail: true,
22
+ optimization: {
23
+ minimizer: [
24
+ new UglifyJsPlugin({
25
+ parallel: true,
26
+ cache: true,
27
+ sourceMap: true,
28
+ uglifyOptions: {
29
+ ecma: 8,
30
+ compress: {
31
+ warnings: false,
32
+ comparisons: false
33
+ },
34
+ mangle: {
35
+ safari10: true
36
+ },
37
+ output: {
38
+ comments: false,
39
+ ascii_only: true
40
+ }
41
+ }
42
+ })
43
+ ]
44
+ }
55
45
  })
56
46
  }
57
47
  }
@@ -2,31 +2,10 @@
2
2
 
3
3
  const deepAssign = require('../deep_assign')
4
4
 
5
- describe('deepAssign()', () => {
6
- test('deeply assigns nested properties', () => {
7
- const object = { foo: { bar: { } } }
8
- const path = 'foo.bar'
9
- const value = { x: 1, y: 2 }
10
- const expectation = { foo: { bar: { x: 1, y: 2 } } }
11
- expect(deepAssign(object, path, value)).toEqual(expectation)
12
- })
13
-
14
- test('allows assignment of a literal false', () => {
15
- const object = { foo: { bar: { } } }
16
- const path = 'foo.bar'
17
- const value = false
18
- const expectation = { foo: { bar: false } }
19
- expect(deepAssign(object, path, value)).toEqual(expectation)
20
- })
21
-
22
- test('does not allow assignment of other falsy values', () => {
23
- const object = { foo: { bar: { } } }
24
- const path = 'foo.bar'
25
- const values = [undefined, null, 0, '']
26
-
27
- values.forEach(value => {
28
- const expectation = new Error(`Value can't be ${value}`)
29
- expect(() => deepAssign(object, path, value)).toThrow(expectation)
30
- })
31
- })
5
+ test('deep assign property', () => {
6
+ const object = { foo: { bar: { } } }
7
+ const path = 'foo.bar'
8
+ const value = { x: 1, y: 2 }
9
+ const expectation = { foo: { bar: { x: 1, y: 2 } } }
10
+ expect(deepAssign(object, path, value)).toEqual(expectation)
32
11
  })
@@ -2,7 +2,7 @@ const { canMerge, prettyPrint } = require('./helpers')
2
2
  const deepMerge = require('./deep_merge')
3
3
 
4
4
  const deepAssign = (obj, path, value) => {
5
- if (!value && value !== false) throw new Error(`Value can't be ${value}`)
5
+ if (!value) throw new Error(`Value can't be ${value}`)
6
6
 
7
7
  const keys = path.split('.')
8
8
  const key = keys.pop()
@@ -1,4 +1,4 @@
1
- const ExtractTextPlugin = require('extract-text-webpack-plugin')
1
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
2
2
  const path = require('path')
3
3
  const devServer = require('../dev_server')
4
4
  const { nodeEnv } = require('../env')
@@ -18,46 +18,35 @@ const styleLoader = {
18
18
  }
19
19
 
20
20
  const getStyleRule = (test, modules = false, preprocessors = []) => {
21
- const extractOptions = {
22
- fallback: styleLoader,
23
- use: [
24
- {
25
- loader: 'css-loader',
26
- options: {
27
- minimize: isProduction,
28
- sourceMap: true,
29
- importLoaders: 2,
30
- modules
31
- }
32
- },
33
- {
34
- loader: 'postcss-loader',
35
- options: {
36
- sourceMap: true,
37
- config: { path: postcssConfigPath }
38
- }
39
- },
40
- ...preprocessors
41
- ]
42
- }
21
+ const use = [
22
+ {
23
+ loader: 'css-loader',
24
+ options: {
25
+ minimize: isProduction,
26
+ sourceMap: true,
27
+ importLoaders: 2,
28
+ modules
29
+ }
30
+ },
31
+ {
32
+ loader: 'postcss-loader',
33
+ options: {
34
+ sourceMap: true,
35
+ config: { path: postcssConfigPath }
36
+ }
37
+ },
38
+ ...preprocessors
39
+ ]
43
40
 
44
41
  const options = modules ? { include: /\.module\.[a-z]+$/ } : { exclude: /\.module\.[a-z]+$/ }
45
42
 
46
- // For production extract styles to a separate bundle
47
- const extractCSSLoader = Object.assign(
48
- {},
49
- { test, use: ExtractTextPlugin.extract(extractOptions) },
50
- options
51
- )
52
-
53
- // For hot-reloading use regular loaders
54
- const inlineCSSLoader = Object.assign(
55
- {},
56
- { test, use: [styleLoader].concat(extractOptions.use) },
57
- options
58
- )
43
+ if (extractCSS) {
44
+ use.unshift(MiniCssExtractPlugin.loader)
45
+ } else {
46
+ use.unshift(styleLoader)
47
+ }
59
48
 
60
- return extractCSS ? extractCSSLoader : inlineCSSLoader
49
+ return Object.assign({}, { test, use }, options)
61
50
  }
62
51
 
63
52
  module.exports = getStyleRule
@@ -1,90 +1,66 @@
1
1
  require "test_helper"
2
2
 
3
3
  class ConfigurationTest < Webpacker::Test
4
- def setup
5
- @config = Webpacker::Configuration.new(
6
- root_path: Pathname.new(File.expand_path("test_app", __dir__)),
7
- config_path: Pathname.new(File.expand_path("./test_app/config/webpacker.yml", __dir__)),
8
- env: "production"
9
- )
10
- end
11
-
12
4
  def test_source_path
13
5
  source_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/javascript").to_s
14
- assert_equal source_path, @config.source_path.to_s
6
+ assert_equal source_path, Webpacker.config.source_path.to_s
15
7
  end
16
8
 
17
9
  def test_source_entry_path
18
10
  source_entry_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/javascript", "packs").to_s
19
- assert_equal @config.source_entry_path.to_s, source_entry_path
11
+ assert_equal Webpacker.config.source_entry_path.to_s, source_entry_path
20
12
  end
21
13
 
22
14
  def test_public_output_path
23
15
  public_output_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs").to_s
24
- assert_equal @config.public_output_path.to_s, public_output_path
16
+ assert_equal Webpacker.config.public_output_path.to_s, public_output_path
25
17
  end
26
18
 
27
19
  def test_public_manifest_path
28
20
  public_manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
29
- assert_equal @config.public_manifest_path.to_s, public_manifest_path
21
+ assert_equal Webpacker.config.public_manifest_path.to_s, public_manifest_path
30
22
  end
31
23
 
32
24
  def test_cache_path
33
25
  cache_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/tmp/cache/webpacker").to_s
34
- assert_equal @config.cache_path.to_s, cache_path
26
+ assert_equal Webpacker.config.cache_path.to_s, cache_path
35
27
  end
36
28
 
37
29
  def test_resolved_paths
38
- assert_equal @config.resolved_paths, ["app/assets", "/etc/yarn"]
30
+ assert_equal Webpacker.config.resolved_paths, ["app/assets", "/etc/yarn"]
39
31
  end
40
32
 
41
33
  def test_resolved_paths_globbed
42
- assert_equal @config.resolved_paths_globbed, ["app/assets/**/*", "/etc/yarn/**/*"]
34
+ assert_equal Webpacker.config.resolved_paths_globbed, ["app/assets/**/*", "/etc/yarn/**/*"]
43
35
  end
44
36
 
45
37
  def test_extensions
46
38
  config_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/config/webpacker.yml").to_s
47
39
  webpacker_yml = YAML.load_file(config_path)
48
- assert_equal @config.extensions, webpacker_yml["default"]["extensions"]
40
+ assert_equal Webpacker.config.extensions, webpacker_yml["default"]["extensions"]
49
41
  end
50
42
 
51
43
  def test_cache_manifest?
52
- assert @config.cache_manifest?
53
-
54
- @config = Webpacker::Configuration.new(
55
- root_path: @config.root_path,
56
- config_path: @config.config_path,
57
- env: "development"
58
- )
44
+ assert Webpacker.config.cache_manifest?
59
45
 
60
- refute @config.cache_manifest?
46
+ with_rails_env("development") do
47
+ refute Webpacker.config.cache_manifest?
48
+ end
61
49
 
62
- @config = Webpacker::Configuration.new(
63
- root_path: @config.root_path,
64
- config_path: @config.config_path,
65
- env: "test"
66
- )
67
-
68
- refute @config.cache_manifest?
50
+ with_rails_env("test") do
51
+ refute Webpacker.config.cache_manifest?
52
+ end
69
53
  end
70
54
 
71
55
  def test_compile?
72
- refute @config.compile?
73
-
74
- @config = Webpacker::Configuration.new(
75
- root_path: @config.root_path,
76
- config_path: @config.config_path,
77
- env: "development"
78
- )
79
-
80
- assert @config.compile?
56
+ refute Webpacker.config.compile?
81
57
 
82
- @config = Webpacker::Configuration.new(
83
- root_path: @config.root_path,
84
- config_path: @config.config_path,
85
- env: "test"
86
- )
58
+ with_rails_env("development") do
59
+ assert Webpacker.config.compile?
60
+ end
87
61
 
88
- assert @config.compile?
62
+ with_rails_env("test") do
63
+ assert Webpacker.config.compile?
64
+ end
89
65
  end
90
66
  end