webpacker 5.2.1 → 6.0.0.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 (154) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +1 -1
  3. data/.gitignore +2 -0
  4. data/.node-version +1 -1
  5. data/.rubocop.yml +11 -16
  6. data/CHANGELOG.md +15 -4
  7. data/CONTRIBUTING.md +1 -1
  8. data/Gemfile.lock +17 -11
  9. data/README.md +8 -4
  10. data/docs/assets.md +21 -5
  11. data/docs/css.md +24 -29
  12. data/docs/deployment.md +18 -0
  13. data/docs/docker.md +2 -2
  14. data/docs/engines.md +1 -1
  15. data/docs/env.md +5 -0
  16. data/docs/es6.md +1 -1
  17. data/docs/integrations.md +1 -1
  18. data/docs/props.md +2 -38
  19. data/docs/react.md +183 -0
  20. data/docs/testing.md +11 -0
  21. data/docs/typescript.md +2 -2
  22. data/docs/webpack-dev-server.md +17 -15
  23. data/docs/webpack.md +58 -107
  24. data/lib/install/config/webpack/base.js +3 -0
  25. data/lib/install/config/webpack/development.js +2 -2
  26. data/lib/install/config/webpack/production.js +2 -2
  27. data/lib/install/config/webpack/test.js +2 -2
  28. data/lib/install/config/webpacker.yml +8 -37
  29. data/lib/install/examples/{vue → vue3}/app.vue +10 -5
  30. data/lib/install/examples/vue3/hello_vue.js +15 -0
  31. data/lib/install/javascript/packs/application.css +9 -0
  32. data/lib/install/template.rb +33 -19
  33. data/lib/tasks/webpacker.rake +2 -11
  34. data/lib/tasks/webpacker/binstubs.rake +6 -4
  35. data/lib/tasks/webpacker/check_binstubs.rake +4 -4
  36. data/lib/tasks/webpacker/check_yarn.rake +1 -2
  37. data/lib/tasks/webpacker/compile.rake +4 -2
  38. data/lib/tasks/webpacker/info.rake +12 -10
  39. data/lib/tasks/webpacker/install.rake +6 -4
  40. data/lib/tasks/webpacker/verify_install.rake +2 -1
  41. data/lib/tasks/webpacker/yarn_install.rake +9 -1
  42. data/lib/webpacker/commands.rb +1 -1
  43. data/lib/webpacker/compiler.rb +7 -6
  44. data/lib/webpacker/configuration.rb +6 -30
  45. data/lib/webpacker/dev_server_runner.rb +21 -2
  46. data/lib/webpacker/helper.rb +22 -32
  47. data/lib/webpacker/manifest.rb +1 -1
  48. data/lib/webpacker/version.rb +1 -1
  49. data/lib/webpacker/webpack_runner.rb +5 -0
  50. data/package.json +23 -39
  51. data/package/__tests__/config.js +5 -37
  52. data/package/__tests__/development.js +9 -11
  53. data/package/__tests__/env.js +12 -4
  54. data/package/__tests__/production.js +6 -6
  55. data/package/__tests__/staging.js +7 -6
  56. data/package/__tests__/test.js +4 -5
  57. data/package/babel/preset-react.js +62 -0
  58. data/package/babel/preset.js +44 -0
  59. data/package/config.js +3 -11
  60. data/package/env.js +8 -2
  61. data/package/environments/__tests__/base.js +15 -47
  62. data/package/environments/base.js +66 -126
  63. data/package/environments/development.js +45 -44
  64. data/package/environments/production.js +69 -65
  65. data/package/environments/test.js +2 -2
  66. data/package/index.js +6 -6
  67. data/package/rules/babel.js +9 -7
  68. data/package/rules/coffee.js +6 -0
  69. data/package/rules/erb.js +13 -0
  70. data/package/rules/file.js +19 -19
  71. data/package/rules/index.js +24 -18
  72. data/package/rules/less.js +18 -0
  73. data/package/rules/sass.js +5 -6
  74. data/package/rules/svg.js +23 -0
  75. data/package/utils/get_style_rule.js +22 -28
  76. data/package/utils/helpers.js +3 -35
  77. data/test/compiler_test.rb +0 -12
  78. data/test/configuration_test.rb +1 -32
  79. data/test/dev_server_runner_test.rb +24 -5
  80. data/test/engine_rake_tasks_test.rb +39 -0
  81. data/test/helper_test.rb +15 -9
  82. data/test/mounted_app/Rakefile +4 -0
  83. data/test/mounted_app/test/dummy/Rakefile +3 -0
  84. data/test/mounted_app/test/dummy/bin/rails +3 -0
  85. data/test/mounted_app/test/dummy/bin/rake +3 -0
  86. data/test/mounted_app/test/dummy/config.ru +5 -0
  87. data/test/mounted_app/test/dummy/config/application.rb +10 -0
  88. data/test/mounted_app/test/dummy/config/environment.rb +3 -0
  89. data/test/mounted_app/test/dummy/config/webpacker.yml +75 -0
  90. data/test/mounted_app/test/dummy/package.json +7 -0
  91. data/test/rake_tasks_test.rb +1 -10
  92. data/test/test_app/config/webpacker.yml +1 -25
  93. data/test/test_app/config/webpacker_public_root.yml +0 -1
  94. data/test/test_app/public/packs/manifest.json +17 -13
  95. data/test/test_app/some.config.js +0 -0
  96. data/test/webpack_runner_test.rb +9 -3
  97. data/webpacker.gemspec +1 -1
  98. data/yarn.lock +1858 -4915
  99. metadata +47 -70
  100. data/.travis.yml +0 -43
  101. data/lib/install/angular.rb +0 -23
  102. data/lib/install/coffee.rb +0 -25
  103. data/lib/install/config/.browserslistrc +0 -1
  104. data/lib/install/config/babel.config.js +0 -70
  105. data/lib/install/config/postcss.config.js +0 -12
  106. data/lib/install/config/webpack/environment.js +0 -3
  107. data/lib/install/elm.rb +0 -39
  108. data/lib/install/erb.rb +0 -25
  109. data/lib/install/examples/angular/hello_angular.js +0 -7
  110. data/lib/install/examples/angular/hello_angular/app/app.component.ts +0 -9
  111. data/lib/install/examples/angular/hello_angular/app/app.module.ts +0 -16
  112. data/lib/install/examples/angular/hello_angular/index.ts +0 -8
  113. data/lib/install/examples/angular/hello_angular/polyfills.ts +0 -73
  114. data/lib/install/examples/coffee/hello_coffee.coffee +0 -4
  115. data/lib/install/examples/elm/Main.elm +0 -55
  116. data/lib/install/examples/elm/hello_elm.js +0 -16
  117. data/lib/install/examples/erb/hello_erb.js.erb +0 -6
  118. data/lib/install/examples/react/babel.config.js +0 -87
  119. data/lib/install/examples/react/hello_react.jsx +0 -26
  120. data/lib/install/examples/react/tsconfig.json +0 -21
  121. data/lib/install/examples/stimulus/application.js +0 -1
  122. data/lib/install/examples/stimulus/controllers/hello_controller.js +0 -18
  123. data/lib/install/examples/stimulus/controllers/index.js +0 -9
  124. data/lib/install/examples/svelte/app.svelte +0 -11
  125. data/lib/install/examples/svelte/hello_svelte.js +0 -20
  126. data/lib/install/examples/typescript/hello_typescript.ts +0 -4
  127. data/lib/install/examples/typescript/tsconfig.json +0 -24
  128. data/lib/install/examples/vue/hello_vue.js +0 -72
  129. data/lib/install/loaders/coffee.js +0 -6
  130. data/lib/install/loaders/elm.js +0 -25
  131. data/lib/install/loaders/erb.js +0 -11
  132. data/lib/install/loaders/svelte.js +0 -9
  133. data/lib/install/loaders/vue.js +0 -6
  134. data/lib/install/react.rb +0 -18
  135. data/lib/install/stimulus.rb +0 -12
  136. data/lib/install/svelte.rb +0 -29
  137. data/lib/install/typescript.rb +0 -39
  138. data/lib/install/vue.rb +0 -49
  139. data/lib/tasks/installers.rake +0 -42
  140. data/package/config_types/__tests__/config_list.js +0 -118
  141. data/package/config_types/__tests__/config_object.js +0 -43
  142. data/package/config_types/config_list.js +0 -75
  143. data/package/config_types/config_object.js +0 -55
  144. data/package/config_types/index.js +0 -7
  145. data/package/rules/module.css.js +0 -3
  146. data/package/rules/module.sass.js +0 -8
  147. data/package/rules/node_modules.js +0 -22
  148. data/package/utils/__tests__/deep_assign.js +0 -32
  149. data/package/utils/__tests__/deep_merge.js +0 -10
  150. data/package/utils/__tests__/get_style_rule.js +0 -65
  151. data/package/utils/__tests__/objectify.js +0 -9
  152. data/package/utils/deep_assign.js +0 -22
  153. data/package/utils/deep_merge.js +0 -22
  154. data/package/utils/objectify.js +0 -3
@@ -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,62 @@
1
+ module.exports = function config(api) {
2
+ const validEnv = ['development', 'test', 'production']
3
+ const currentEnv = api.env()
4
+ const isDevelopmentEnv = api.env('development')
5
+ const isProductionEnv = api.env('production')
6
+ const isTestEnv = api.env('test')
7
+
8
+ if (!validEnv.includes(currentEnv)) {
9
+ throw new Error(
10
+ `Please specify a valid NODE_ENV or BABEL_ENV environment variable. Valid values are "development", "test", and "production". Instead, received: "${JSON.stringify(currentEnv)}".`
11
+ )
12
+ }
13
+
14
+ return {
15
+ presets: [
16
+ isTestEnv && [
17
+ '@babel/preset-env',
18
+ {
19
+ targets: { node: 'current' },
20
+ modules: 'commonjs'
21
+ }
22
+ ],
23
+ (isProductionEnv || isDevelopmentEnv) && [
24
+ '@babel/preset-env',
25
+ {
26
+ useBuiltIns: 'entry',
27
+ corejs: '3.8',
28
+ modules: false,
29
+ bugfixes: true,
30
+ loose: true,
31
+ exclude: ['transform-typeof-symbol']
32
+ }
33
+ ],
34
+ [
35
+ '@babel/preset-react',
36
+ {
37
+ development: isDevelopmentEnv || isTestEnv,
38
+ useBuiltIns: true
39
+ }
40
+ ]
41
+ ].filter(Boolean),
42
+ plugins: [
43
+ 'babel-plugin-macros',
44
+ [
45
+ '@babel/plugin-proposal-class-properties',
46
+ { loose: true }
47
+ ],
48
+ [
49
+ '@babel/plugin-transform-runtime',
50
+ {
51
+ helpers: false,
52
+ regenerator: true,
53
+ corejs: false
54
+ }
55
+ ],
56
+ isProductionEnv && [
57
+ 'babel-plugin-transform-react-remove-prop-types',
58
+ { removeImport: true }
59
+ ]
60
+ ].filter(Boolean)
61
+ }
62
+ }
@@ -0,0 +1,44 @@
1
+ module.exports = function config(api) {
2
+ const validEnv = ['development', 'test', 'production']
3
+ const currentEnv = api.env()
4
+ const isDevelopmentEnv = api.env('development')
5
+ const isProductionEnv = api.env('production')
6
+ const isTestEnv = api.env('test')
7
+
8
+ if (!validEnv.includes(currentEnv)) {
9
+ throw new Error(
10
+ `Please specify a valid NODE_ENV or BABEL_ENV environment variable. Valid values are "development", "test", and "production". Instead, received: "${JSON.stringify(currentEnv)}".`
11
+ )
12
+ }
13
+
14
+ return {
15
+ presets: [
16
+ isTestEnv && [
17
+ '@babel/preset-env',
18
+ { targets: { node: 'current' } }
19
+ ],
20
+ (isProductionEnv || isDevelopmentEnv) && [
21
+ '@babel/preset-env',
22
+ {
23
+ useBuiltIns: 'entry',
24
+ corejs: '3.8',
25
+ modules: 'auto',
26
+ bugfixes: true,
27
+ loose: true,
28
+ exclude: ['transform-typeof-symbol']
29
+ }
30
+ ]
31
+ ].filter(Boolean),
32
+ plugins: [
33
+ 'babel-plugin-macros',
34
+ [
35
+ '@babel/plugin-proposal-class-properties',
36
+ { loose: true }
37
+ ],
38
+ [
39
+ '@babel/plugin-transform-runtime',
40
+ { helpers: false }
41
+ ]
42
+ ].filter(Boolean)
43
+ }
44
+ }
@@ -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 = () => {
@@ -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(4)
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,116 @@
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 } = 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')
58
14
 
59
15
  const getEntryObject = () => {
60
- const result = new ConfigObject()
61
- const glob = getExtensionsGlob()
16
+ const entries = {}
62
17
  const rootPath = join(config.source_path, config.source_entry_path)
63
- const paths = sync(join(rootPath, glob))
64
- paths.forEach((path) => {
18
+
19
+ sync(`${rootPath}/**/*.*`).forEach((path) => {
65
20
  const namespace = relative(join(rootPath), dirname(path))
66
21
  const name = join(namespace, basename(path, extname(path)))
67
22
  let assetPaths = resolve(path)
68
23
 
69
24
  // Allows for multiple filetypes per entry (https://webpack.js.org/guides/entry-advanced/)
70
25
  // Transforms the config object value to an array with all values under the same name
71
- let previousPaths = result.get(name)
26
+ let previousPaths = entries[name]
72
27
  if (previousPaths) {
73
- previousPaths = Array.isArray(previousPaths) ? previousPaths : [previousPaths]
28
+ previousPaths = Array.isArray(previousPaths)
29
+ ? previousPaths
30
+ : [previousPaths]
74
31
  previousPaths.push(assetPaths)
75
32
  assetPaths = previousPaths
76
33
  }
77
34
 
78
- result.set(name, assetPaths)
35
+ entries[name] = assetPaths
79
36
  })
80
- return result
37
+
38
+ return entries
81
39
  }
82
40
 
83
41
  const getModulePaths = () => {
84
- const result = new ConfigList()
85
- result.append('source', resolve(config.source_path))
42
+ const result = [resolve(config.source_path)]
43
+
86
44
  if (config.additional_paths) {
87
- config.additional_paths.forEach((path) => result.append(path, resolve(path)))
45
+ config.additional_paths.forEach((path) => result.push(resolve(path)))
88
46
  }
89
- result.append('node_modules', 'node_modules')
47
+ result.push('node_modules')
48
+
90
49
  return result
91
50
  }
92
51
 
93
- const getBaseConfig = () => new ConfigObject({
52
+ const getPlugins = () => {
53
+ const plugins = [
54
+ new webpack.EnvironmentPlugin(process.env),
55
+ PnpWebpackPlugin,
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
+ try {
67
+ if (require.resolve('css-loader')) {
68
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
69
+ plugins.push(
70
+ new MiniCssExtractPlugin({
71
+ filename: isDevelopment ? '[name].css' : '[name].[contenthash:8].css',
72
+ chunkFilename: isDevelopment ? '[id].css' : '[id].[contenthash:8].css'
73
+ })
74
+ )
75
+ }
76
+ } catch (e) {
77
+ /* Work out what to print here */
78
+ }
79
+
80
+ return plugins
81
+ }
82
+
83
+ module.exports = {
94
84
  mode: 'production',
95
85
  output: {
96
86
  filename: 'js/[name]-[contenthash].js',
97
87
  chunkFilename: 'js/[name]-[contenthash].chunk.js',
98
88
  hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js',
89
+ assetModuleFilename: 'static/[hash][ext][query]',
99
90
  path: config.outputPath,
100
91
  publicPath: config.publicPath
101
92
  },
102
-
93
+ entry: getEntryObject(),
103
94
  resolve: {
104
- extensions: config.extensions,
105
- plugins: [PnpWebpackPlugin]
95
+ extensions: ['.js', '.mjs', '.ts'],
96
+ modules: getModulePaths()
106
97
  },
107
98
 
99
+ plugins: getPlugins(),
100
+
108
101
  resolveLoader: {
109
102
  modules: ['node_modules'],
110
103
  plugins: [PnpWebpackPlugin.moduleLoader(module)]
111
104
  },
112
105
 
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
- }
106
+ optimization: {
107
+ splitChunks: { chunks: 'all' },
156
108
 
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(),
109
+ runtimeChunk: { name: (entrypoint) => `runtime-${entrypoint.name}` }
110
+ },
170
111
 
171
- resolve: {
172
- modules: this.resolvedModules.values()
173
- }
174
- })
112
+ module: {
113
+ strictExportPresence: true,
114
+ rules
175
115
  }
176
116
  }