webpacker 5.4.4 → 6.0.0.beta

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 (159) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +1 -1
  3. data/.github/workflows/ruby.yml +28 -4
  4. data/.gitignore +2 -0
  5. data/.node-version +1 -1
  6. data/.rubocop.yml +3 -111
  7. data/6_0_upgrade.md +43 -0
  8. data/CHANGELOG.md +19 -26
  9. data/Gemfile.lock +91 -94
  10. data/README.md +215 -98
  11. data/gemfiles/Gemfile-rails-edge +1 -1
  12. data/lib/install/config/webpack/base.js +3 -0
  13. data/lib/install/config/webpack/development.js +2 -2
  14. data/lib/install/config/webpack/production.js +2 -2
  15. data/lib/install/config/webpack/test.js +2 -2
  16. data/lib/install/config/webpacker.yml +8 -37
  17. data/lib/install/javascript/packs/application.css +9 -0
  18. data/lib/install/javascript/packs/application.js +3 -1
  19. data/lib/install/template.rb +33 -27
  20. data/lib/tasks/webpacker/binstubs.rake +6 -4
  21. data/lib/tasks/webpacker/check_binstubs.rake +4 -4
  22. data/lib/tasks/webpacker/check_yarn.rake +1 -1
  23. data/lib/tasks/webpacker/compile.rake +4 -2
  24. data/lib/tasks/webpacker/info.rake +12 -10
  25. data/lib/tasks/webpacker/install.rake +6 -4
  26. data/lib/tasks/webpacker/verify_install.rake +2 -1
  27. data/lib/tasks/webpacker/yarn_install.rake +9 -7
  28. data/lib/tasks/webpacker.rake +2 -11
  29. data/lib/webpacker/compiler.rb +15 -8
  30. data/lib/webpacker/configuration.rb +10 -45
  31. data/lib/webpacker/dev_server_runner.rb +21 -2
  32. data/lib/webpacker/env.rb +1 -5
  33. data/lib/webpacker/helper.rb +22 -32
  34. data/lib/webpacker/manifest.rb +1 -1
  35. data/lib/webpacker/version.rb +1 -1
  36. data/lib/webpacker/webpack_runner.rb +5 -0
  37. data/package/__tests__/config.js +5 -37
  38. data/package/__tests__/development.js +9 -11
  39. data/package/__tests__/env.js +12 -4
  40. data/package/__tests__/production.js +6 -6
  41. data/package/__tests__/staging.js +7 -6
  42. data/package/__tests__/test.js +4 -5
  43. data/package/babel/preset.js +55 -0
  44. data/package/config.js +3 -11
  45. data/package/env.js +8 -2
  46. data/package/environments/__tests__/base.js +15 -47
  47. data/package/environments/base.js +62 -125
  48. data/package/environments/development.js +45 -44
  49. data/package/environments/production.js +63 -68
  50. data/package/environments/test.js +2 -2
  51. data/package/index.js +13 -8
  52. data/package/rules/babel.js +9 -7
  53. data/package/rules/coffee.js +6 -0
  54. data/package/rules/erb.js +15 -0
  55. data/package/rules/file.js +19 -19
  56. data/package/rules/index.js +15 -18
  57. data/package/rules/less.js +22 -0
  58. data/package/rules/sass.js +10 -10
  59. data/package/rules/svg.js +20 -0
  60. data/package/utils/get_style_rule.js +26 -36
  61. data/package/utils/helpers.js +26 -35
  62. data/package.json +29 -45
  63. data/test/compiler_test.rb +0 -12
  64. data/test/configuration_test.rb +1 -32
  65. data/test/dev_server_runner_test.rb +24 -5
  66. data/test/engine_rake_tasks_test.rb +39 -0
  67. data/test/helper_test.rb +24 -30
  68. data/test/mounted_app/Rakefile +4 -0
  69. data/test/mounted_app/test/dummy/Rakefile +3 -0
  70. data/test/mounted_app/test/dummy/bin/rails +3 -0
  71. data/test/mounted_app/test/dummy/bin/rake +3 -0
  72. data/test/mounted_app/test/dummy/config/application.rb +10 -0
  73. data/test/mounted_app/test/dummy/config/environment.rb +3 -0
  74. data/test/mounted_app/test/dummy/config/webpacker.yml +75 -0
  75. data/test/mounted_app/test/dummy/config.ru +5 -0
  76. data/test/mounted_app/test/dummy/package.json +7 -0
  77. data/test/rake_tasks_test.rb +1 -10
  78. data/test/test_app/config/webpacker.yml +1 -25
  79. data/test/test_app/config/webpacker_public_root.yml +0 -1
  80. data/test/test_app/public/packs/manifest.json +17 -13
  81. data/test/test_app/some.config.js +0 -0
  82. data/test/webpack_runner_test.rb +9 -3
  83. data/yarn.lock +2505 -4943
  84. metadata +37 -82
  85. data/docs/assets.md +0 -119
  86. data/docs/cloud9.md +0 -310
  87. data/docs/css.md +0 -308
  88. data/docs/deployment.md +0 -130
  89. data/docs/docker.md +0 -68
  90. data/docs/engines.md +0 -213
  91. data/docs/env.md +0 -63
  92. data/docs/es6.md +0 -72
  93. data/docs/folder-structure.md +0 -66
  94. data/docs/integrations.md +0 -220
  95. data/docs/misc.md +0 -23
  96. data/docs/props.md +0 -223
  97. data/docs/target.md +0 -22
  98. data/docs/testing.md +0 -136
  99. data/docs/troubleshooting.md +0 -158
  100. data/docs/typescript.md +0 -190
  101. data/docs/v4-upgrade.md +0 -142
  102. data/docs/webpack-dev-server.md +0 -92
  103. data/docs/webpack.md +0 -364
  104. data/docs/yarn.md +0 -23
  105. data/lib/install/angular.rb +0 -23
  106. data/lib/install/coffee.rb +0 -25
  107. data/lib/install/config/.browserslistrc +0 -1
  108. data/lib/install/config/babel.config.js +0 -82
  109. data/lib/install/config/postcss.config.js +0 -12
  110. data/lib/install/config/webpack/environment.js +0 -3
  111. data/lib/install/elm.rb +0 -39
  112. data/lib/install/erb.rb +0 -25
  113. data/lib/install/examples/angular/hello_angular/app/app.component.ts +0 -9
  114. data/lib/install/examples/angular/hello_angular/app/app.module.ts +0 -16
  115. data/lib/install/examples/angular/hello_angular/index.ts +0 -8
  116. data/lib/install/examples/angular/hello_angular/polyfills.ts +0 -73
  117. data/lib/install/examples/angular/hello_angular.js +0 -7
  118. data/lib/install/examples/coffee/hello_coffee.coffee +0 -4
  119. data/lib/install/examples/elm/Main.elm +0 -55
  120. data/lib/install/examples/elm/hello_elm.js +0 -16
  121. data/lib/install/examples/erb/hello_erb.js.erb +0 -6
  122. data/lib/install/examples/react/babel.config.js +0 -99
  123. data/lib/install/examples/react/hello_react.jsx +0 -26
  124. data/lib/install/examples/react/tsconfig.json +0 -21
  125. data/lib/install/examples/stimulus/application.js +0 -1
  126. data/lib/install/examples/stimulus/controllers/hello_controller.js +0 -18
  127. data/lib/install/examples/stimulus/controllers/index.js +0 -9
  128. data/lib/install/examples/svelte/app.svelte +0 -11
  129. data/lib/install/examples/svelte/hello_svelte.js +0 -20
  130. data/lib/install/examples/typescript/hello_typescript.ts +0 -4
  131. data/lib/install/examples/typescript/tsconfig.json +0 -24
  132. data/lib/install/examples/vue/app.vue +0 -22
  133. data/lib/install/examples/vue/hello_vue.js +0 -72
  134. data/lib/install/loaders/coffee.js +0 -6
  135. data/lib/install/loaders/elm.js +0 -25
  136. data/lib/install/loaders/erb.js +0 -11
  137. data/lib/install/loaders/svelte.js +0 -9
  138. data/lib/install/loaders/vue.js +0 -6
  139. data/lib/install/react.rb +0 -18
  140. data/lib/install/stimulus.rb +0 -12
  141. data/lib/install/svelte.rb +0 -29
  142. data/lib/install/typescript.rb +0 -39
  143. data/lib/install/vue.rb +0 -49
  144. data/lib/tasks/installers.rake +0 -42
  145. data/package/config_types/__tests__/config_list.js +0 -118
  146. data/package/config_types/__tests__/config_object.js +0 -43
  147. data/package/config_types/config_list.js +0 -75
  148. data/package/config_types/config_object.js +0 -55
  149. data/package/config_types/index.js +0 -7
  150. data/package/rules/module.css.js +0 -3
  151. data/package/rules/module.sass.js +0 -8
  152. data/package/rules/node_modules.js +0 -22
  153. data/package/utils/__tests__/deep_assign.js +0 -32
  154. data/package/utils/__tests__/deep_merge.js +0 -10
  155. data/package/utils/__tests__/get_style_rule.js +0 -65
  156. data/package/utils/__tests__/objectify.js +0 -9
  157. data/package/utils/deep_assign.js +0 -22
  158. data/package/utils/deep_merge.js +0 -22
  159. data/package/utils/objectify.js +0 -3
@@ -8,19 +8,20 @@ chdirTestApp()
8
8
  describe('Custom environment', () => {
9
9
  afterAll(chdirCwd)
10
10
 
11
- describe('toWebpackConfig', () => {
11
+ describe('webpackConfig', () => {
12
12
  beforeEach(() => jest.resetModules())
13
13
 
14
14
  test('should use staging config and default production environment', () => {
15
15
  process.env.RAILS_ENV = 'staging'
16
16
  delete process.env.NODE_ENV
17
17
 
18
- const { environment } = require('../index')
19
- const config = environment.toWebpackConfig()
18
+ const { webpackConfig } = require('../index')
20
19
 
21
- expect(config.output.path).toEqual(resolve('public', 'packs-staging'))
22
- expect(config.output.publicPath).toEqual('/packs-staging/')
23
- expect(config).toMatchObject({
20
+ expect(webpackConfig.output.path).toEqual(
21
+ resolve('public', 'packs-staging')
22
+ )
23
+ expect(webpackConfig.output.publicPath).toEqual('/packs-staging/')
24
+ expect(webpackConfig).toMatchObject({
24
25
  devtool: 'source-map',
25
26
  stats: 'normal'
26
27
  })
@@ -15,12 +15,11 @@ describe('Test environment', () => {
15
15
  process.env.RAILS_ENV = 'test'
16
16
  process.env.NODE_ENV = 'test'
17
17
 
18
- const { environment } = require('../index')
19
- const config = environment.toWebpackConfig()
18
+ const { webpackConfig } = require('../index')
20
19
 
21
- expect(config.output.path).toEqual(resolve('public', 'packs-test'))
22
- expect(config.output.publicPath).toEqual('/packs-test/')
23
- expect(config.devServer).toEqual(undefined)
20
+ expect(webpackConfig.output.path).toEqual(resolve('public', 'packs-test'))
21
+ expect(webpackConfig.output.publicPath).toEqual('/packs-test/')
22
+ expect(webpackConfig.devServer).toEqual(undefined)
24
23
  })
25
24
  })
26
25
  })
@@ -0,0 +1,55 @@
1
+ const { moduleExists } = require('@rails/webpacker')
2
+
3
+ module.exports = function config(api) {
4
+ const validEnv = ['development', 'test', 'production']
5
+ const currentEnv = api.env()
6
+ const isDevelopmentEnv = api.env('development')
7
+ const isProductionEnv = api.env('production')
8
+ const isTestEnv = api.env('test')
9
+
10
+ if (!validEnv.includes(currentEnv)) {
11
+ throw new Error(
12
+ `Please specify a valid NODE_ENV or BABEL_ENV environment variable. Valid values are "development", "test", and "production". Instead, received: "${JSON.stringify(
13
+ currentEnv
14
+ )}".`
15
+ )
16
+ }
17
+
18
+ return {
19
+ presets: [
20
+ isTestEnv && ['@babel/preset-env', { targets: { node: 'current' } }],
21
+ (isProductionEnv || isDevelopmentEnv) && [
22
+ '@babel/preset-env',
23
+ {
24
+ useBuiltIns: 'entry',
25
+ corejs: '3.8',
26
+ modules: 'auto',
27
+ bugfixes: true,
28
+ loose: true,
29
+ exclude: ['transform-typeof-symbol']
30
+ }
31
+ ],
32
+ moduleExists('@babel/preset-typescript') && [
33
+ '@babel/preset-typescript',
34
+ { allExtensions: true, isTSX: true }
35
+ ],
36
+ moduleExists('@babel/preset-react') && [
37
+ '@babel/preset-react',
38
+ {
39
+ development: isDevelopmentEnv || isTestEnv,
40
+ useBuiltIns: true
41
+ }
42
+ ]
43
+ ].filter(Boolean),
44
+ plugins: [
45
+ 'babel-plugin-macros',
46
+ ['@babel/plugin-proposal-class-properties', { loose: true }],
47
+ ['@babel/plugin-transform-runtime', { helpers: false }],
48
+ isProductionEnv &&
49
+ moduleExists('babel-plugin-transform-react-remove-prop-types') && [
50
+ 'babel-plugin-transform-react-remove-prop-types',
51
+ { removeImport: true }
52
+ ]
53
+ ].filter(Boolean)
54
+ }
55
+ }
data/package/config.js CHANGED
@@ -1,8 +1,8 @@
1
1
  const { resolve } = require('path')
2
2
  const { safeLoad } = require('js-yaml')
3
3
  const { readFileSync } = require('fs')
4
- const deepMerge = require('./utils/deep_merge')
5
- const { isArray, ensureTrailingSlash } = require('./utils/helpers')
4
+ const { merge } = require('webpack-merge')
5
+ const { ensureTrailingSlash } = require('./utils/helpers')
6
6
  const { railsEnv } = require('./env')
7
7
  const configPath = require('./configPath')
8
8
 
@@ -16,17 +16,9 @@ const getDefaultConfig = () => {
16
16
  const defaults = getDefaultConfig()
17
17
  const app = safeLoad(readFileSync(configPath), 'utf8')[railsEnv]
18
18
 
19
- if (isArray(app.extensions) && app.extensions.length) delete defaults.extensions
20
- if (isArray(app.static_assets_extensions) && app.static_assets_extensions.length) {
21
- delete defaults.static_assets_extensions
22
- }
23
-
24
- const config = deepMerge(defaults, app)
19
+ const config = merge(defaults, app)
25
20
  config.outputPath = resolve(config.public_root_path, config.public_output_path)
26
21
 
27
- // Merge resolved_paths into additional_paths for backwards-compat
28
- config.additional_paths = config.additional_paths.concat(config.resolved_paths || [])
29
-
30
22
  // Ensure that the publicPath includes our asset host so dynamic imports
31
23
  // (code-splitting chunks and static assets) load from the CDN instead of a relative path.
32
24
  const getPublicPath = () => {
data/package/env.js CHANGED
@@ -6,7 +6,11 @@ const DEFAULT = 'production'
6
6
  const configPath = require('./configPath')
7
7
 
8
8
  const railsEnv = process.env.RAILS_ENV
9
- const nodeEnv = process.env.NODE_ENV
9
+ const rawNodeEnv = process.env.NODE_ENV
10
+ const nodeEnv
11
+ = rawNodeEnv && NODE_ENVIRONMENTS.includes(rawNodeEnv) ? rawNodeEnv : DEFAULT
12
+ const isProduction = nodeEnv === 'production'
13
+ const isDevelopment = nodeEnv === 'development'
10
14
 
11
15
  const config = safeLoad(readFileSync(configPath), 'utf8')
12
16
  const availableEnvironments = Object.keys(config).join('|')
@@ -14,5 +18,7 @@ const regex = new RegExp(`^(${availableEnvironments})$`, 'g')
14
18
 
15
19
  module.exports = {
16
20
  railsEnv: railsEnv && railsEnv.match(regex) ? railsEnv : DEFAULT,
17
- nodeEnv: nodeEnv && NODE_ENVIRONMENTS.includes(nodeEnv) ? nodeEnv : DEFAULT
21
+ nodeEnv,
22
+ isProduction,
23
+ isDevelopment
18
24
  }
@@ -9,93 +9,61 @@ chdirTestApp()
9
9
 
10
10
  const { resolve } = require('path')
11
11
  const rules = require('../../rules')
12
- const { ConfigList } = require('../../config_types')
13
- const Environment = require('../base')
12
+ const baseConfig = require('../base')
14
13
 
15
- describe('Environment', () => {
14
+ describe('Base config', () => {
16
15
  afterAll(chdirCwd)
17
16
 
18
- let environment
19
-
20
- describe('toWebpackConfig', () => {
21
- beforeEach(() => {
22
- environment = new Environment()
23
- })
24
-
17
+ describe('config', () => {
25
18
  test('should return entry', () => {
26
- const config = environment.toWebpackConfig()
27
- expect(config.entry.application).toEqual(
19
+ expect(baseConfig.entry.application).toEqual(
28
20
  resolve('app', 'javascript', 'packs', 'application.js')
29
21
  )
30
22
  })
31
23
 
32
24
  test('should return multi file entry points', () => {
33
- const config = environment.toWebpackConfig()
34
- expect(config.entry.multi_entry.sort()).toEqual([
25
+ expect(baseConfig.entry.multi_entry.sort()).toEqual([
35
26
  resolve('app', 'javascript', 'packs', 'multi_entry.css'),
36
27
  resolve('app', 'javascript', 'packs', 'multi_entry.js')
37
28
  ])
38
29
  })
39
30
 
40
31
  test('should return output', () => {
41
- const config = environment.toWebpackConfig()
42
- expect(config.output.filename).toEqual('js/[name]-[contenthash].js')
43
- expect(config.output.chunkFilename).toEqual(
32
+ expect(baseConfig.output.filename).toEqual('js/[name]-[contenthash].js')
33
+ expect(baseConfig.output.chunkFilename).toEqual(
44
34
  'js/[name]-[contenthash].chunk.js'
45
35
  )
46
36
  })
47
37
 
48
38
  test('should return default loader rules for each file in config/loaders', () => {
49
- const config = environment.toWebpackConfig()
50
39
  const defaultRules = Object.keys(rules)
51
- const configRules = config.module.rules
52
-
53
- expect(defaultRules.length).toEqual(7)
54
- expect(configRules.length).toEqual(7)
55
- })
56
-
57
- test('should return cache path for nodeModules rule', () => {
58
- const nodeModulesLoader = rules.nodeModules.use.find(
59
- (rule) => rule.loader === 'babel-loader'
60
- )
61
-
62
- expect(nodeModulesLoader.options.cacheDirectory).toBeTruthy()
63
- })
40
+ const configRules = baseConfig.module.rules
64
41
 
65
- test('should return cache path for babel-loader rule', () => {
66
- const babelLoader = rules.babel.use.find(
67
- (rule) => rule.loader === 'babel-loader'
68
- )
69
-
70
- expect(babelLoader.options.cacheDirectory).toBeTruthy()
42
+ expect(defaultRules.length).toEqual(3)
43
+ expect(configRules.length).toEqual(3)
71
44
  })
72
45
 
73
46
  test('should return default plugins', () => {
74
- const config = environment.toWebpackConfig()
75
- expect(config.plugins.length).toEqual(4)
47
+ expect(baseConfig.plugins.length).toEqual(3)
76
48
  })
77
49
 
78
50
  test('should return default resolveLoader', () => {
79
- const config = environment.toWebpackConfig()
80
- expect(config.resolveLoader.modules).toEqual(['node_modules'])
51
+ expect(baseConfig.resolveLoader.modules).toEqual(['node_modules'])
81
52
  })
82
53
 
83
54
  test('should return default resolve.modules with additions', () => {
84
- const config = environment.toWebpackConfig()
85
- expect(config.resolve.modules).toEqual([
55
+ expect(baseConfig.resolve.modules).toEqual([
86
56
  resolve('app', 'javascript'),
87
57
  resolve('app/assets'),
88
58
  resolve('/etc/yarn'),
59
+ resolve('some.config.js'),
89
60
  resolve('app/elm'),
90
61
  'node_modules'
91
62
  ])
92
63
  })
93
64
 
94
65
  test('returns plugins property as Array', () => {
95
- const config = environment.toWebpackConfig()
96
-
97
- expect(config.plugins).toBeInstanceOf(Array)
98
- expect(config.plugins).not.toBeInstanceOf(ConfigList)
66
+ expect(baseConfig.plugins).toBeInstanceOf(Array)
99
67
  })
100
68
  })
101
69
  })
@@ -1,176 +1,113 @@
1
1
  /* eslint global-require: 0 */
2
2
  /* eslint import/no-dynamic-require: 0 */
3
3
 
4
- const {
5
- basename, dirname, join, relative, resolve
6
- } = require('path')
7
- const { sync } = require('glob')
4
+ const { basename, dirname, join, relative, resolve } = require('path')
8
5
  const extname = require('path-complete-extname')
9
-
10
- const webpack = require('webpack')
11
- const MiniCssExtractPlugin = require('mini-css-extract-plugin')
12
- const WebpackAssetsManifest = require('webpack-assets-manifest')
13
- const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
14
6
  const PnpWebpackPlugin = require('pnp-webpack-plugin')
15
-
16
- const { isNotObject, prettyPrint } = require('../utils/helpers')
17
- const deepMerge = require('../utils/deep_merge')
18
-
19
- const { ConfigList, ConfigObject } = require('../config_types')
7
+ const { sync: globSync } = require('glob')
8
+ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
9
+ const WebpackAssetsManifest = require('webpack-assets-manifest')
10
+ const webpack = require('webpack')
20
11
  const rules = require('../rules')
21
12
  const config = require('../config')
22
-
23
- const getLoaderList = () => {
24
- const result = new ConfigList()
25
- Object.keys(rules).forEach((key) => result.append(key, rules[key]))
26
- return result
27
- }
28
-
29
- const getPluginList = () => {
30
- const result = new ConfigList()
31
- result.append(
32
- 'Environment',
33
- new webpack.EnvironmentPlugin(process.env)
34
- )
35
- result.append('CaseSensitivePaths', new CaseSensitivePathsPlugin())
36
- result.append(
37
- 'MiniCssExtract',
38
- new MiniCssExtractPlugin({
39
- filename: 'css/[name]-[contenthash:8].css',
40
- chunkFilename: 'css/[name]-[contenthash:8].chunk.css'
41
- })
42
- )
43
- result.append(
44
- 'Manifest',
45
- new WebpackAssetsManifest({
46
- entrypoints: true,
47
- writeToDisk: true,
48
- publicPath: config.publicPathWithoutCDN
49
- })
50
- )
51
- return result
52
- }
53
-
54
- const getExtensionsGlob = () => {
55
- const { extensions } = config
56
- return extensions.length === 1 ? `**/*${extensions[0]}` : `**/*{${extensions.join(',')}}`
57
- }
13
+ const { isDevelopment } = require('../env')
14
+ const { moduleExists } = require('../utils/helpers')
58
15
 
59
16
  const getEntryObject = () => {
60
- const result = new ConfigObject()
61
- const glob = getExtensionsGlob()
17
+ const entries = {}
62
18
  const rootPath = join(config.source_path, config.source_entry_path)
63
- const paths = sync(join(rootPath, glob))
64
- paths.forEach((path) => {
19
+
20
+ globSync(`${rootPath}/**/*.*`).forEach((path) => {
65
21
  const namespace = relative(join(rootPath), dirname(path))
66
22
  const name = join(namespace, basename(path, extname(path)))
67
23
  let assetPaths = resolve(path)
68
24
 
69
25
  // Allows for multiple filetypes per entry (https://webpack.js.org/guides/entry-advanced/)
70
26
  // Transforms the config object value to an array with all values under the same name
71
- let previousPaths = result.get(name)
27
+ let previousPaths = entries[name]
72
28
  if (previousPaths) {
73
- previousPaths = Array.isArray(previousPaths) ? previousPaths : [previousPaths]
29
+ previousPaths = Array.isArray(previousPaths)
30
+ ? previousPaths
31
+ : [previousPaths]
74
32
  previousPaths.push(assetPaths)
75
33
  assetPaths = previousPaths
76
34
  }
77
35
 
78
- result.set(name, assetPaths)
36
+ entries[name] = assetPaths
79
37
  })
80
- return result
38
+
39
+ return entries
81
40
  }
82
41
 
83
42
  const getModulePaths = () => {
84
- const result = new ConfigList()
85
- result.append('source', resolve(config.source_path))
43
+ const result = [resolve(config.source_path)]
44
+
86
45
  if (config.additional_paths) {
87
- config.additional_paths.forEach((path) => result.append(path, resolve(path)))
46
+ config.additional_paths.forEach((path) => result.push(resolve(path)))
88
47
  }
89
- result.append('node_modules', 'node_modules')
48
+ result.push('node_modules')
49
+
90
50
  return result
91
51
  }
92
52
 
93
- const getBaseConfig = () => new ConfigObject({
53
+ const getPlugins = () => {
54
+ const plugins = [
55
+ new webpack.EnvironmentPlugin(process.env),
56
+ new CaseSensitivePathsPlugin(),
57
+ new WebpackAssetsManifest({
58
+ entrypoints: true,
59
+ writeToDisk: true,
60
+ output: 'manifest.json',
61
+ entrypointsUseAssets: true,
62
+ publicPath: true
63
+ })
64
+ ]
65
+
66
+ if (moduleExists('css-loader') && moduleExists('mini-css-extract-plugin')) {
67
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
68
+ plugins.push(
69
+ new MiniCssExtractPlugin({
70
+ filename: isDevelopment ? '[name].css' : '[name].[contenthash:8].css',
71
+ chunkFilename: isDevelopment ? '[id].css' : '[id].[contenthash:8].css'
72
+ })
73
+ )
74
+ }
75
+
76
+ return plugins
77
+ }
78
+
79
+ module.exports = {
94
80
  mode: 'production',
95
81
  output: {
96
82
  filename: 'js/[name]-[contenthash].js',
97
83
  chunkFilename: 'js/[name]-[contenthash].chunk.js',
98
84
  hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js',
85
+ assetModuleFilename: 'static/[hash][ext][query]',
99
86
  path: config.outputPath,
100
87
  publicPath: config.publicPath
101
88
  },
102
-
89
+ entry: getEntryObject(),
103
90
  resolve: {
104
- extensions: config.extensions,
91
+ extensions: ['.js', '.mjs', '.ts', '.coffee'],
92
+ modules: getModulePaths(),
105
93
  plugins: [PnpWebpackPlugin]
106
94
  },
107
95
 
96
+ plugins: getPlugins(),
97
+
108
98
  resolveLoader: {
109
99
  modules: ['node_modules'],
110
100
  plugins: [PnpWebpackPlugin.moduleLoader(module)]
111
101
  },
112
102
 
113
- node: {
114
- dgram: 'empty',
115
- fs: 'empty',
116
- net: 'empty',
117
- tls: 'empty',
118
- child_process: 'empty'
119
- }
120
- })
121
-
122
- module.exports = class Base {
123
- constructor() {
124
- this.loaders = getLoaderList()
125
- this.plugins = getPluginList()
126
- this.config = getBaseConfig()
127
- this.entry = getEntryObject()
128
- this.resolvedModules = getModulePaths()
129
- }
130
-
131
- splitChunks(callback = null) {
132
- let appConfig = {}
133
- const defaultConfig = {
134
- optimization: {
135
- // Split vendor and common chunks
136
- // https://twitter.com/wSokra/status/969633336732905474
137
- splitChunks: {
138
- chunks: 'all',
139
- name: true
140
- },
141
- // Separate runtime chunk to enable long term caching
142
- // https://twitter.com/wSokra/status/969679223278505985
143
- runtimeChunk: true
144
- }
145
- }
146
-
147
- if (callback) {
148
- appConfig = callback(defaultConfig)
149
- if (isNotObject(appConfig)) {
150
- throw new Error(`
151
- ${prettyPrint(appConfig)} is not a valid splitChunks configuration.
152
- See https://webpack.js.org/plugins/split-chunks-plugin/#configuration
153
- `)
154
- }
155
- }
103
+ optimization: {
104
+ splitChunks: { chunks: 'all' },
156
105
 
157
- return this.config.merge(deepMerge(defaultConfig, appConfig))
158
- }
159
-
160
- toWebpackConfig() {
161
- return this.config.merge({
162
- entry: this.entry.toObject(),
163
-
164
- module: {
165
- strictExportPresence: true,
166
- rules: this.loaders.values()
167
- },
168
-
169
- plugins: this.plugins.values(),
106
+ runtimeChunk: 'single'
107
+ },
170
108
 
171
- resolve: {
172
- modules: this.resolvedModules.values()
173
- }
174
- })
109
+ module: {
110
+ strictExportPresence: true,
111
+ rules
175
112
  }
176
113
  }
@@ -1,53 +1,54 @@
1
+ const { merge } = require('webpack-merge')
1
2
  const webpack = require('webpack')
2
- const Base = require('./base')
3
+
4
+ const baseConfig = require('./base')
3
5
  const devServer = require('../dev_server')
6
+
4
7
  const { outputPath: contentBase, publicPath } = require('../config')
5
8
 
6
- module.exports = class extends Base {
7
- constructor() {
8
- super()
9
+ let devConfig = {
10
+ mode: 'development',
11
+ devtool: 'cheap-module-source-map'
12
+ }
9
13
 
10
- this.config.merge({
11
- mode: 'development',
12
- devtool: 'cheap-module-source-map'
14
+ if (
15
+ process.env.WEBPACK_DEV_SERVER &&
16
+ process.env.WEBPACK_DEV_SERVER !== 'undefined'
17
+ ) {
18
+ if (devServer.hmr) {
19
+ devConfig = merge(devConfig, {
20
+ output: { filename: '[name]-[hash].js' },
21
+ plugins: [new webpack.HotModuleReplacementPlugin()]
13
22
  })
23
+ }
14
24
 
15
- if (process.env.WEBPACK_DEV_SERVER
16
- && process.env.WEBPACK_DEV_SERVER !== 'undefined') {
17
- if (devServer.hmr) {
18
- this.plugins.append('HotModuleReplacement', new webpack.HotModuleReplacementPlugin())
19
- this.config.output.filename = '[name]-[hash].js'
20
- }
21
-
22
- this.config.merge({
23
- devServer: {
24
- clientLogLevel: 'none',
25
- compress: devServer.compress,
26
- quiet: devServer.quiet,
27
- disableHostCheck: devServer.disable_host_check,
28
- host: devServer.host,
29
- port: devServer.port,
30
- https: devServer.https,
31
- hot: devServer.hmr,
32
- contentBase,
33
- inline: devServer.inline,
34
- useLocalIp: devServer.use_local_ip,
35
- public: devServer.public,
36
- publicPath,
37
- historyApiFallback: {
38
- disableDotRule: true
39
- },
40
- headers: devServer.headers,
41
- overlay: devServer.overlay,
42
- stats: {
43
- entrypoints: false,
44
- errorDetails: true,
45
- modules: false,
46
- moduleTrace: false
47
- },
48
- watchOptions: devServer.watch_options
49
- }
50
- })
25
+ devConfig = merge(devConfig, {
26
+ devServer: {
27
+ clientLogLevel: 'none',
28
+ compress: devServer.compress,
29
+ quiet: devServer.quiet,
30
+ disableHostCheck: devServer.disable_host_check,
31
+ host: devServer.host,
32
+ port: devServer.port,
33
+ https: devServer.https,
34
+ hot: devServer.hmr,
35
+ contentBase,
36
+ inline: devServer.inline,
37
+ useLocalIp: devServer.use_local_ip,
38
+ public: devServer.public,
39
+ publicPath,
40
+ historyApiFallback: { disableDotRule: true },
41
+ headers: devServer.headers,
42
+ overlay: devServer.overlay,
43
+ stats: {
44
+ entrypoints: false,
45
+ errorDetails: true,
46
+ modules: false,
47
+ moduleTrace: false
48
+ },
49
+ watchOptions: devServer.watch_options
51
50
  }
52
- }
51
+ })
53
52
  }
53
+
54
+ module.exports = merge(baseConfig, devConfig)