webpacker 5.2.1 → 6.0.0.beta.4

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 (169) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +1 -1
  3. data/.github/workflows/jest.yml +1 -1
  4. data/.github/workflows/js-lint.yml +1 -1
  5. data/.github/workflows/ruby.yml +9 -6
  6. data/.gitignore +2 -0
  7. data/.node-version +1 -1
  8. data/.rubocop.yml +11 -16
  9. data/6_0_upgrade.md +48 -0
  10. data/CHANGELOG.md +27 -0
  11. data/CONTRIBUTING.md +1 -1
  12. data/Gemfile.lock +23 -15
  13. data/README.md +252 -103
  14. data/config/README.md +3 -0
  15. data/config/webpacker.yml +1 -0
  16. data/lib/install/config/webpack/base.js +3 -0
  17. data/lib/install/config/webpack/development.js +2 -2
  18. data/lib/install/config/webpack/production.js +2 -2
  19. data/lib/install/config/webpack/test.js +2 -2
  20. data/lib/install/config/webpacker.yml +12 -39
  21. data/lib/install/{javascript/packs → packs/entrypoints}/application.js +5 -3
  22. data/lib/install/template.rb +36 -22
  23. data/lib/tasks/webpacker.rake +2 -11
  24. data/lib/tasks/webpacker/binstubs.rake +6 -4
  25. data/lib/tasks/webpacker/check_binstubs.rake +4 -4
  26. data/lib/tasks/webpacker/check_yarn.rake +1 -2
  27. data/lib/tasks/webpacker/compile.rake +4 -2
  28. data/lib/tasks/webpacker/info.rake +12 -10
  29. data/lib/tasks/webpacker/install.rake +6 -4
  30. data/lib/tasks/webpacker/verify_install.rake +2 -1
  31. data/lib/tasks/webpacker/yarn_install.rake +9 -1
  32. data/lib/webpacker/commands.rb +3 -2
  33. data/lib/webpacker/compiler.rb +16 -9
  34. data/lib/webpacker/configuration.rb +6 -30
  35. data/lib/webpacker/dev_server_runner.rb +23 -2
  36. data/lib/webpacker/helper.rb +26 -36
  37. data/lib/webpacker/manifest.rb +1 -1
  38. data/lib/webpacker/version.rb +1 -1
  39. data/lib/webpacker/webpack_runner.rb +6 -0
  40. data/package.json +23 -39
  41. data/package/__tests__/config.js +5 -37
  42. data/package/__tests__/development.js +11 -12
  43. data/package/__tests__/env.js +12 -4
  44. data/package/__tests__/index.js +9 -0
  45. data/package/__tests__/production.js +6 -6
  46. data/package/__tests__/staging.js +7 -6
  47. data/package/__tests__/test.js +4 -5
  48. data/package/babel/preset.js +55 -0
  49. data/package/config.js +3 -11
  50. data/package/env.js +8 -2
  51. data/package/environments/__tests__/base.js +19 -51
  52. data/package/environments/base.js +65 -125
  53. data/package/environments/development.js +46 -44
  54. data/package/environments/production.js +66 -64
  55. data/package/environments/test.js +2 -2
  56. data/package/index.js +13 -8
  57. data/package/rules/babel.js +9 -7
  58. data/package/rules/coffee.js +6 -0
  59. data/package/rules/erb.js +15 -0
  60. data/package/rules/file.js +21 -19
  61. data/package/rules/index.js +16 -18
  62. data/package/rules/less.js +22 -0
  63. data/package/rules/raw.js +5 -0
  64. data/package/rules/sass.js +12 -9
  65. data/package/rules/stylus.js +26 -0
  66. data/package/utils/get_style_rule.js +26 -36
  67. data/package/utils/helpers.js +26 -35
  68. data/test/compiler_test.rb +0 -12
  69. data/test/configuration_test.rb +3 -34
  70. data/test/dev_server_runner_test.rb +33 -6
  71. data/test/engine_rake_tasks_test.rb +39 -0
  72. data/test/helper_test.rb +15 -9
  73. data/test/mounted_app/Rakefile +4 -0
  74. data/test/mounted_app/test/dummy/Rakefile +3 -0
  75. data/test/mounted_app/test/dummy/bin/rails +3 -0
  76. data/test/mounted_app/test/dummy/bin/rake +3 -0
  77. data/test/mounted_app/test/dummy/config.ru +5 -0
  78. data/test/mounted_app/test/dummy/config/application.rb +10 -0
  79. data/test/mounted_app/test/dummy/config/environment.rb +3 -0
  80. data/test/mounted_app/test/dummy/config/webpacker.yml +75 -0
  81. data/test/mounted_app/test/dummy/package.json +7 -0
  82. data/test/rake_tasks_test.rb +1 -10
  83. data/test/test_app/app/{javascript/packs → packs/entrypoints}/application.js +1 -1
  84. data/test/test_app/app/{javascript/packs → packs/entrypoints}/multi_entry.css +0 -0
  85. data/test/test_app/app/{javascript/packs → packs/entrypoints}/multi_entry.js +0 -0
  86. data/test/test_app/config/webpacker.yml +3 -27
  87. data/test/test_app/config/webpacker_public_root.yml +0 -1
  88. data/test/test_app/public/packs/manifest.json +17 -13
  89. data/test/test_app/some.config.js +0 -0
  90. data/test/webpack_runner_test.rb +9 -3
  91. data/webpacker.gemspec +1 -1
  92. data/yarn.lock +1858 -4915
  93. metadata +54 -97
  94. data/.travis.yml +0 -43
  95. data/docs/assets.md +0 -119
  96. data/docs/cloud9.md +0 -310
  97. data/docs/css.md +0 -308
  98. data/docs/deployment.md +0 -130
  99. data/docs/docker.md +0 -68
  100. data/docs/engines.md +0 -213
  101. data/docs/env.md +0 -63
  102. data/docs/es6.md +0 -72
  103. data/docs/folder-structure.md +0 -66
  104. data/docs/integrations.md +0 -220
  105. data/docs/misc.md +0 -23
  106. data/docs/props.md +0 -223
  107. data/docs/target.md +0 -22
  108. data/docs/testing.md +0 -136
  109. data/docs/troubleshooting.md +0 -158
  110. data/docs/typescript.md +0 -190
  111. data/docs/v4-upgrade.md +0 -142
  112. data/docs/webpack-dev-server.md +0 -92
  113. data/docs/webpack.md +0 -364
  114. data/docs/yarn.md +0 -23
  115. data/lib/install/angular.rb +0 -23
  116. data/lib/install/coffee.rb +0 -25
  117. data/lib/install/config/.browserslistrc +0 -1
  118. data/lib/install/config/babel.config.js +0 -70
  119. data/lib/install/config/postcss.config.js +0 -12
  120. data/lib/install/config/webpack/environment.js +0 -3
  121. data/lib/install/elm.rb +0 -39
  122. data/lib/install/erb.rb +0 -25
  123. data/lib/install/examples/angular/hello_angular.js +0 -7
  124. data/lib/install/examples/angular/hello_angular/app/app.component.ts +0 -9
  125. data/lib/install/examples/angular/hello_angular/app/app.module.ts +0 -16
  126. data/lib/install/examples/angular/hello_angular/index.ts +0 -8
  127. data/lib/install/examples/angular/hello_angular/polyfills.ts +0 -73
  128. data/lib/install/examples/coffee/hello_coffee.coffee +0 -4
  129. data/lib/install/examples/elm/Main.elm +0 -55
  130. data/lib/install/examples/elm/hello_elm.js +0 -16
  131. data/lib/install/examples/erb/hello_erb.js.erb +0 -6
  132. data/lib/install/examples/react/babel.config.js +0 -87
  133. data/lib/install/examples/react/hello_react.jsx +0 -26
  134. data/lib/install/examples/react/tsconfig.json +0 -21
  135. data/lib/install/examples/stimulus/application.js +0 -1
  136. data/lib/install/examples/stimulus/controllers/hello_controller.js +0 -18
  137. data/lib/install/examples/stimulus/controllers/index.js +0 -9
  138. data/lib/install/examples/svelte/app.svelte +0 -11
  139. data/lib/install/examples/svelte/hello_svelte.js +0 -20
  140. data/lib/install/examples/typescript/hello_typescript.ts +0 -4
  141. data/lib/install/examples/typescript/tsconfig.json +0 -24
  142. data/lib/install/examples/vue/app.vue +0 -22
  143. data/lib/install/examples/vue/hello_vue.js +0 -72
  144. data/lib/install/loaders/coffee.js +0 -6
  145. data/lib/install/loaders/elm.js +0 -25
  146. data/lib/install/loaders/erb.js +0 -11
  147. data/lib/install/loaders/svelte.js +0 -9
  148. data/lib/install/loaders/vue.js +0 -6
  149. data/lib/install/react.rb +0 -18
  150. data/lib/install/stimulus.rb +0 -12
  151. data/lib/install/svelte.rb +0 -29
  152. data/lib/install/typescript.rb +0 -39
  153. data/lib/install/vue.rb +0 -49
  154. data/lib/tasks/installers.rake +0 -42
  155. data/package/config_types/__tests__/config_list.js +0 -118
  156. data/package/config_types/__tests__/config_object.js +0 -43
  157. data/package/config_types/config_list.js +0 -75
  158. data/package/config_types/config_object.js +0 -55
  159. data/package/config_types/index.js +0 -7
  160. data/package/rules/module.css.js +0 -3
  161. data/package/rules/module.sass.js +0 -8
  162. data/package/rules/node_modules.js +0 -22
  163. data/package/utils/__tests__/deep_assign.js +0 -32
  164. data/package/utils/__tests__/deep_merge.js +0 -10
  165. data/package/utils/__tests__/get_style_rule.js +0 -65
  166. data/package/utils/__tests__/objectify.js +0 -9
  167. data/package/utils/deep_assign.js +0 -22
  168. data/package/utils/deep_merge.js +0 -22
  169. data/package/utils/objectify.js +0 -3
@@ -13,7 +13,9 @@ describe('Env', () => {
13
13
  process.env.NODE_ENV = 'development'
14
14
  expect(require('../env')).toEqual({
15
15
  railsEnv: 'development',
16
- nodeEnv: 'development'
16
+ nodeEnv: 'development',
17
+ isProduction: false,
18
+ isDevelopment: true
17
19
  })
18
20
  })
19
21
 
@@ -22,7 +24,9 @@ describe('Env', () => {
22
24
  delete process.env.NODE_ENV
23
25
  expect(require('../env')).toEqual({
24
26
  railsEnv: 'development',
25
- nodeEnv: 'production'
27
+ nodeEnv: 'production',
28
+ isProduction: true,
29
+ isDevelopment: false
26
30
  })
27
31
  })
28
32
 
@@ -31,7 +35,9 @@ describe('Env', () => {
31
35
  delete process.env.RAILS_ENV
32
36
  expect(require('../env')).toEqual({
33
37
  railsEnv: 'production',
34
- nodeEnv: 'production'
38
+ nodeEnv: 'production',
39
+ isProduction: true,
40
+ isDevelopment: false
35
41
  })
36
42
  })
37
43
 
@@ -40,7 +46,9 @@ describe('Env', () => {
40
46
  process.env.NODE_ENV = 'staging'
41
47
  expect(require('../env')).toEqual({
42
48
  railsEnv: 'staging',
43
- nodeEnv: 'production'
49
+ nodeEnv: 'production',
50
+ isProduction: true,
51
+ isDevelopment: false
44
52
  })
45
53
  })
46
54
  })
@@ -0,0 +1,9 @@
1
+ const index = require('../index')
2
+
3
+ describe('index', () => {
4
+ test('exports webpack-merge v5 functions', () => {
5
+ expect(index.merge).toBeInstanceOf(Function)
6
+ expect(index.mergeWithRules).toBeInstanceOf(Function)
7
+ expect(index.mergeWithCustomize).toBeInstanceOf(Function)
8
+ })
9
+ })
@@ -8,19 +8,19 @@ chdirTestApp()
8
8
  describe('Production 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 production config and environment', () => {
15
15
  process.env.RAILS_ENV = 'production'
16
16
  process.env.NODE_ENV = 'production'
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'))
22
- expect(config.output.publicPath).toEqual('/packs/')
23
- expect(config).toMatchObject({
20
+ expect(webpackConfig.output.path).toEqual(resolve('public', 'packs'))
21
+ expect(webpackConfig.output.publicPath).toEqual('/packs/')
22
+
23
+ expect(webpackConfig).toMatchObject({
24
24
  devtool: 'source-map',
25
25
  stats: 'normal'
26
26
  })
@@ -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
+ }
@@ -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(
28
- resolve('app', 'javascript', 'packs', 'application.js')
19
+ expect(baseConfig.entry.application).toEqual(
20
+ resolve('app', 'packs', 'entrypoints', '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([
35
- resolve('app', 'javascript', 'packs', 'multi_entry.css'),
36
- resolve('app', 'javascript', 'packs', 'multi_entry.js')
25
+ expect(baseConfig.entry.multi_entry.sort()).toEqual([
26
+ resolve('app', 'packs', 'entrypoints', 'multi_entry.css'),
27
+ resolve('app', 'packs', 'entrypoints', '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([
86
- resolve('app', 'javascript'),
55
+ expect(baseConfig.resolve.modules).toEqual([
56
+ resolve('app', 'packs'),
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,96 +1,86 @@
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
71
+ ? 'css/[name].css'
72
+ : 'css/[name]-[contenthash:8].css',
73
+ chunkFilename: isDevelopment
74
+ ? 'css/[id].css'
75
+ : 'css/[id]-[contenthash:8].css'
76
+ })
77
+ )
78
+ }
79
+
80
+ return plugins
81
+ }
82
+
83
+ module.exports = {
94
84
  mode: 'production',
95
85
  output: {
96
86
  filename: 'js/[name]-[contenthash].js',
@@ -99,78 +89,28 @@ const getBaseConfig = () => new ConfigObject({
99
89
  path: config.outputPath,
100
90
  publicPath: config.publicPath
101
91
  },
102
-
92
+ entry: getEntryObject(),
103
93
  resolve: {
104
- extensions: config.extensions,
94
+ extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.coffee'],
95
+ modules: getModulePaths(),
105
96
  plugins: [PnpWebpackPlugin]
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: 'single'
110
+ },
170
111
 
171
- resolve: {
172
- modules: this.resolvedModules.values()
173
- }
174
- })
112
+ module: {
113
+ strictExportPresence: true,
114
+ rules
175
115
  }
176
116
  }