webpacker 6.0.0.beta.6 → 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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/jest.yml +1 -1
  3. data/.github/workflows/js-lint.yml +1 -1
  4. data/.github/workflows/ruby.yml +6 -9
  5. data/CHANGELOG.md +4 -20
  6. data/CONTRIBUTING.md +1 -1
  7. data/Gemfile.lock +5 -7
  8. data/README.md +109 -306
  9. data/docs/assets.md +135 -0
  10. data/docs/cloud9.md +310 -0
  11. data/docs/css.md +303 -0
  12. data/docs/deployment.md +148 -0
  13. data/docs/docker.md +68 -0
  14. data/docs/engines.md +213 -0
  15. data/docs/env.md +68 -0
  16. data/docs/es6.md +72 -0
  17. data/docs/folder-structure.md +66 -0
  18. data/docs/integrations.md +220 -0
  19. data/docs/misc.md +23 -0
  20. data/docs/props.md +187 -0
  21. data/docs/react.md +183 -0
  22. data/docs/target.md +22 -0
  23. data/docs/testing.md +147 -0
  24. data/docs/troubleshooting.md +3 -5
  25. data/docs/typescript.md +190 -0
  26. data/docs/v4-upgrade.md +142 -0
  27. data/docs/webpack-dev-server.md +94 -0
  28. data/docs/webpack.md +315 -0
  29. data/docs/yarn.md +23 -0
  30. data/lib/install/config/webpacker.yml +2 -4
  31. data/lib/install/examples/vue3/app.vue +27 -0
  32. data/lib/install/examples/vue3/hello_vue.js +15 -0
  33. data/lib/install/javascript/packs/application.css +9 -0
  34. data/lib/install/{packs/entrypoints → javascript/packs}/application.js +2 -4
  35. data/lib/install/template.rb +3 -3
  36. data/lib/webpacker/commands.rb +1 -2
  37. data/lib/webpacker/compiler.rb +3 -9
  38. data/lib/webpacker/dev_server_runner.rb +0 -2
  39. data/lib/webpacker/helper.rb +43 -13
  40. data/lib/webpacker/manifest.rb +1 -1
  41. data/lib/webpacker/version.rb +1 -1
  42. data/lib/webpacker/webpack_runner.rb +0 -1
  43. data/package.json +1 -1
  44. data/package/__tests__/development.js +1 -2
  45. data/package/babel/preset-react.js +62 -0
  46. data/package/babel/preset.js +13 -24
  47. data/package/environments/__tests__/base.js +5 -5
  48. data/package/environments/base.js +19 -19
  49. data/package/environments/development.js +0 -1
  50. data/package/environments/production.js +30 -28
  51. data/package/index.js +2 -7
  52. data/package/rules/babel.js +1 -1
  53. data/package/rules/coffee.js +5 -5
  54. data/package/rules/erb.js +3 -5
  55. data/package/rules/file.js +3 -5
  56. data/package/rules/index.js +17 -9
  57. data/package/rules/less.js +10 -14
  58. data/package/rules/sass.js +9 -13
  59. data/package/rules/svg.js +23 -0
  60. data/package/utils/get_style_rule.js +31 -27
  61. data/package/utils/helpers.js +0 -25
  62. data/test/configuration_test.rb +2 -2
  63. data/test/dev_server_runner_test.rb +2 -10
  64. data/test/helper_test.rb +39 -33
  65. data/test/manifest_test.rb +0 -8
  66. data/test/mounted_app/test/dummy/config/webpacker.yml +2 -2
  67. data/test/test_app/app/{packs/entrypoints → javascript/packs}/application.js +1 -1
  68. data/test/test_app/app/{packs/entrypoints → javascript/packs}/multi_entry.css +0 -0
  69. data/test/test_app/app/{packs/entrypoints → javascript/packs}/multi_entry.js +0 -0
  70. data/test/test_app/config/webpacker.yml +2 -2
  71. data/test/test_app/public/packs/manifest.json +0 -7
  72. metadata +36 -17
  73. data/6_0_upgrade.md +0 -62
  74. data/config/README.md +0 -3
  75. data/config/webpacker.yml +0 -1
  76. data/package/__tests__/index.js +0 -9
  77. data/package/rules/raw.js +0 -5
  78. data/package/rules/stylus.js +0 -26
@@ -17,14 +17,14 @@ describe('Base config', () => {
17
17
  describe('config', () => {
18
18
  test('should return entry', () => {
19
19
  expect(baseConfig.entry.application).toEqual(
20
- resolve('app', 'packs', 'entrypoints', 'application.js')
20
+ resolve('app', 'javascript', 'packs', 'application.js')
21
21
  )
22
22
  })
23
23
 
24
24
  test('should return multi file entry points', () => {
25
25
  expect(baseConfig.entry.multi_entry.sort()).toEqual([
26
- resolve('app', 'packs', 'entrypoints', 'multi_entry.css'),
27
- resolve('app', 'packs', 'entrypoints', 'multi_entry.js')
26
+ resolve('app', 'javascript', 'packs', 'multi_entry.css'),
27
+ resolve('app', 'javascript', 'packs', 'multi_entry.js')
28
28
  ])
29
29
  })
30
30
 
@@ -44,7 +44,7 @@ describe('Base config', () => {
44
44
  })
45
45
 
46
46
  test('should return default plugins', () => {
47
- expect(baseConfig.plugins.length).toEqual(3)
47
+ expect(baseConfig.plugins.length).toEqual(4)
48
48
  })
49
49
 
50
50
  test('should return default resolveLoader', () => {
@@ -53,7 +53,7 @@ describe('Base config', () => {
53
53
 
54
54
  test('should return default resolve.modules with additions', () => {
55
55
  expect(baseConfig.resolve.modules).toEqual([
56
- resolve('app', 'packs'),
56
+ resolve('app', 'javascript'),
57
57
  resolve('app/assets'),
58
58
  resolve('/etc/yarn'),
59
59
  resolve('some.config.js'),
@@ -4,20 +4,19 @@
4
4
  const { basename, dirname, join, relative, resolve } = require('path')
5
5
  const extname = require('path-complete-extname')
6
6
  const PnpWebpackPlugin = require('pnp-webpack-plugin')
7
- const { sync: globSync } = require('glob')
7
+ const { sync } = require('glob')
8
8
  const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
9
9
  const WebpackAssetsManifest = require('webpack-assets-manifest')
10
10
  const webpack = require('webpack')
11
11
  const rules = require('../rules')
12
12
  const config = require('../config')
13
13
  const { isDevelopment } = require('../env')
14
- const { moduleExists } = require('../utils/helpers')
15
14
 
16
15
  const getEntryObject = () => {
17
16
  const entries = {}
18
17
  const rootPath = join(config.source_path, config.source_entry_path)
19
18
 
20
- globSync(`${rootPath}/**/*.*`).forEach((path) => {
19
+ sync(`${rootPath}/**/*.*`).forEach((path) => {
21
20
  const namespace = relative(join(rootPath), dirname(path))
22
21
  const name = join(namespace, basename(path, extname(path)))
23
22
  let assetPaths = resolve(path)
@@ -53,6 +52,7 @@ const getModulePaths = () => {
53
52
  const getPlugins = () => {
54
53
  const plugins = [
55
54
  new webpack.EnvironmentPlugin(process.env),
55
+ PnpWebpackPlugin,
56
56
  new CaseSensitivePathsPlugin(),
57
57
  new WebpackAssetsManifest({
58
58
  entrypoints: true,
@@ -63,18 +63,18 @@ const getPlugins = () => {
63
63
  })
64
64
  ]
65
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
- )
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
78
  }
79
79
 
80
80
  return plugins
@@ -86,14 +86,14 @@ module.exports = {
86
86
  filename: 'js/[name]-[contenthash].js',
87
87
  chunkFilename: 'js/[name]-[contenthash].chunk.js',
88
88
  hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js',
89
+ assetModuleFilename: 'static/[hash][ext][query]',
89
90
  path: config.outputPath,
90
91
  publicPath: config.publicPath
91
92
  },
92
93
  entry: getEntryObject(),
93
94
  resolve: {
94
- extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.coffee'],
95
- modules: getModulePaths(),
96
- plugins: [PnpWebpackPlugin]
95
+ extensions: ['.js', '.mjs', '.ts'],
96
+ modules: getModulePaths()
97
97
  },
98
98
 
99
99
  plugins: getPlugins(),
@@ -106,7 +106,7 @@ module.exports = {
106
106
  optimization: {
107
107
  splitChunks: { chunks: 'all' },
108
108
 
109
- runtimeChunk: 'single'
109
+ runtimeChunk: { name: (entrypoint) => `runtime-${entrypoint.name}` }
110
110
  },
111
111
 
112
112
  module: {
@@ -34,7 +34,6 @@ if (
34
34
  hot: devServer.hmr,
35
35
  contentBase,
36
36
  inline: devServer.inline,
37
- injectClient: devServer.inject_client,
38
37
  useLocalIp: devServer.use_local_ip,
39
38
  public: devServer.public,
40
39
  publicPath,
@@ -5,42 +5,45 @@ const { merge } = require('webpack-merge')
5
5
  const CompressionPlugin = require('compression-webpack-plugin')
6
6
  const TerserPlugin = require('terser-webpack-plugin')
7
7
  const baseConfig = require('./base')
8
- const { moduleExists } = require('../utils/helpers')
9
8
 
10
9
  const getPlugins = () => {
11
- const plugins = []
10
+ let compressionPlugin = new CompressionPlugin({
11
+ filename: '[path].gz[query]',
12
+ algorithm: 'gzip',
13
+ test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
14
+ })
12
15
 
13
- plugins.push(
14
- new CompressionPlugin({
15
- filename: '[path][base].gz[query]',
16
- algorithm: 'gzip',
16
+ if ('brotli' in process.versions) {
17
+ compressionPlugin = new CompressionPlugin({
18
+ filename: '[path].br[query]',
19
+ algorithm: 'brotliCompress',
17
20
  test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
18
21
  })
19
- )
20
-
21
- if ('brotli' in process.versions) {
22
- plugins.push(
23
- new CompressionPlugin({
24
- filename: '[path][base].br[query]',
25
- algorithm: 'brotliCompress',
26
- test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
27
- })
28
- )
29
22
  }
30
23
 
31
- return plugins
32
- }
24
+ const plugins = [compressionPlugin]
33
25
 
34
- const tryCssMinimizer = () => {
35
- if (
36
- moduleExists('css-loader') &&
37
- moduleExists('css-minimizer-webpack-plugin')
38
- ) {
39
- const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
40
- return new CssMinimizerPlugin({ sourceMap: true })
26
+ try {
27
+ if (require.resolve('css-loader')) {
28
+ const OptimizeCSSAssetsPlugin = require.resolve(
29
+ 'optimize-css-assets-webpack-plugin'
30
+ )
31
+ const safePostCssParser = require.resolve('postcss-safe-parser')
32
+ plugins.push(
33
+ new OptimizeCSSAssetsPlugin({
34
+ parser: safePostCssParser,
35
+ map: {
36
+ inline: false,
37
+ annotation: true
38
+ }
39
+ })
40
+ )
41
+ }
42
+ } catch (e) {
43
+ /* Work out what to output without clutter */
41
44
  }
42
45
 
43
- return null
46
+ return plugins
44
47
  }
45
48
 
46
49
  const productionConfig = {
@@ -50,7 +53,6 @@ const productionConfig = {
50
53
  plugins: getPlugins(),
51
54
  optimization: {
52
55
  minimizer: [
53
- tryCssMinimizer(),
54
56
  new TerserPlugin({
55
57
  parallel: Number.parseInt(process.env.WEBPACKER_PARALLEL, 10) || true,
56
58
  terserOptions: {
@@ -72,7 +74,7 @@ const productionConfig = {
72
74
  }
73
75
  }
74
76
  })
75
- ].filter(Boolean)
77
+ ]
76
78
  }
77
79
  }
78
80
 
data/package/index.js CHANGED
@@ -1,15 +1,13 @@
1
1
  /* eslint global-require: 0 */
2
2
  /* eslint import/no-dynamic-require: 0 */
3
3
 
4
- const webpackMerge = require('webpack-merge')
5
4
  const { resolve } = require('path')
6
5
  const { existsSync } = require('fs')
7
6
  const baseConfig = require('./environments/base')
8
- const rules = require('./rules')
7
+ const loaders = require('./rules')
9
8
  const config = require('./config')
10
9
  const devServer = require('./dev_server')
11
10
  const { nodeEnv } = require('./env')
12
- const { moduleExists, canProcess } = require('./utils/helpers')
13
11
 
14
12
  const webpackConfig = () => {
15
13
  const path = resolve(__dirname, 'environments', `${nodeEnv}.js`)
@@ -22,8 +20,5 @@ module.exports = {
22
20
  devServer,
23
21
  webpackConfig: webpackConfig(),
24
22
  baseConfig,
25
- rules,
26
- moduleExists,
27
- canProcess,
28
- ...webpackMerge
23
+ loaders
29
24
  }
@@ -8,7 +8,7 @@ const {
8
8
  const { isProduction } = require('../env')
9
9
 
10
10
  module.exports = {
11
- test: /\.(js|jsx|mjs|ts|tsx|coffee)?(\.erb)?$/,
11
+ test: /\.(js|jsx|mjs|ts|tsx)?(\.erb)?$/,
12
12
  include: [sourcePath, ...additionalPaths].map((p) => {
13
13
  try {
14
14
  return realpathSync(p)
@@ -1,6 +1,6 @@
1
- const { canProcess } = require('../utils/helpers')
2
-
3
- module.exports = canProcess('coffee-loader', (resolvedPath) => ({
1
+ module.exports = {
4
2
  test: /\.coffee(\.erb)?$/,
5
- use: [{ loader: resolvedPath }]
6
- }))
3
+ use: [
4
+ { loader: require.resolve('coffee-loader') }
5
+ ]
6
+ }
data/package/rules/erb.js CHANGED
@@ -1,15 +1,13 @@
1
- const { canProcess } = require('../utils/helpers')
2
-
3
1
  const runner = /^win/.test(process.platform) ? 'ruby ' : ''
4
2
 
5
- module.exports = canProcess('rails-erb-loader', (resolvedPath) => ({
3
+ module.exports = {
6
4
  test: /\.erb$/,
7
5
  enforce: 'pre',
8
6
  exclude: /node_modules/,
9
7
  use: [
10
8
  {
11
- loader: resolvedPath,
9
+ loader: require.resolve('rails-erb-loader'),
12
10
  options: { runner: `${runner}bin/rails runner` }
13
11
  }
14
12
  ]
15
- }))
13
+ }
@@ -13,11 +13,9 @@ module.exports = {
13
13
  /\.ttf$/,
14
14
  /\.woff$/,
15
15
  /\.woff2$/,
16
- /\.svg$/
16
+ /\.html$/,
17
+ /\.json$/
17
18
  ],
18
19
  exclude: [/\.(js|mjs|jsx|ts|tsx)$/],
19
- type: 'asset/resource',
20
- generator: {
21
- filename: 'media/images/[hash][ext][query]'
22
- }
20
+ type: 'asset/resource'
23
21
  }
@@ -1,16 +1,24 @@
1
1
  /* eslint global-require: 0 */
2
2
  /* eslint import/no-dynamic-require: 0 */
3
3
 
4
+ const load = (name) => {
5
+ try {
6
+ return require(`./${name}`)
7
+ } catch (e) {
8
+ return null
9
+ }
10
+ }
11
+
4
12
  const rules = {
5
- raw: require('./raw'),
6
- file: require('./file'),
7
- css: require('./css'),
8
- sass: require('./sass'),
9
- babel: require('./babel'),
10
- erb: require('./erb'),
11
- coffee: require('./coffee'),
12
- less: require('./less'),
13
- stylus: require('./stylus')
13
+ file: load('file'),
14
+ svg: load('svg'),
15
+ css: load('css'),
16
+ sass: load('sass'),
17
+ babel: load('babel'),
18
+ erb: load('erb'),
19
+ coffee: load('coffee'),
20
+ html: load('html'),
21
+ less: load('less')
14
22
  }
15
23
 
16
24
  module.exports = Object.keys(rules)
@@ -1,22 +1,18 @@
1
1
  const path = require('path')
2
- const { canProcess } = require('../utils/helpers')
3
2
  const getStyleRule = require('../utils/get_style_rule')
4
-
5
3
  const {
6
4
  additional_paths: paths,
7
5
  source_path: sourcePath
8
6
  } = require('../config')
9
7
 
10
- module.exports = canProcess('less-loader', (resolvedPath) =>
11
- getStyleRule(/\.(less)(\.erb)?$/i, [
12
- {
13
- loader: resolvedPath,
14
- options: {
15
- lessOptions: {
16
- paths: [path.resolve(__dirname, 'node_modules'), sourcePath, ...paths]
17
- },
18
- sourceMap: true
19
- }
8
+ module.exports = getStyleRule(/\.(less)(\.erb)?$/i, [
9
+ {
10
+ loader: require.resolve('less-loader'),
11
+ options: {
12
+ lessOptions: {
13
+ paths: [path.resolve(__dirname, 'node_modules'), sourcePath, ...paths]
14
+ },
15
+ sourceMap: true
20
16
  }
21
- ])
22
- )
17
+ }
18
+ ])
@@ -1,17 +1,13 @@
1
- /* eslint global-require: 0 */
2
-
1
+ const sass = require('sass')
3
2
  const getStyleRule = require('../utils/get_style_rule')
4
- const { canProcess } = require('../utils/helpers')
5
3
  const { additional_paths: includePaths } = require('../config')
6
4
 
7
- module.exports = canProcess('sass-loader', (resolvedPath) =>
8
- getStyleRule(/\.(scss|sass)(\.erb)?$/i, [
9
- {
10
- loader: resolvedPath,
11
- options: {
12
- sassOptions: { includePaths },
13
- implementation: require('sass')
14
- }
5
+ module.exports = getStyleRule(/\.(scss|sass)(\.erb)?$/i, [
6
+ {
7
+ loader: require.resolve('sass-loader'),
8
+ options: {
9
+ sassOptions: { includePaths },
10
+ implementation: sass
15
11
  }
16
- ])
17
- )
12
+ }
13
+ ])
@@ -0,0 +1,23 @@
1
+ /* eslint global-require: 0 */
2
+ /* eslint import/no-dynamic-require: 0 */
3
+
4
+ module.exports = {
5
+ test: /\.svg$/i,
6
+ type: 'asset/inline',
7
+ generator: {
8
+ dataUrl: (content) => {
9
+ let optimisedContent = content
10
+
11
+ try {
12
+ if (require.resolve('mini-svg-data-uri')) {
13
+ const svgToMiniDataURI = require('mini-svg-data-uri')
14
+ optimisedContent = svgToMiniDataURI(content.toString())
15
+ }
16
+ } catch (e) {
17
+ /* Work out what to print here */
18
+ }
19
+
20
+ return optimisedContent
21
+ }
22
+ }
23
+ }
@@ -1,35 +1,39 @@
1
- /* eslint global-require: 0 */
1
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
2
2
 
3
- const { canProcess, moduleExists } = require('./helpers')
4
-
5
- const getStyleRule = (test, preprocessors = []) => {
6
- if (moduleExists('css-loader')) {
7
- const tryPostcss = () =>
8
- canProcess('postcss-loader', (loaderPath) => ({
9
- loader: loaderPath,
3
+ const tryPostcss = () => {
4
+ let postcssLoader = false
5
+ try {
6
+ if (require.resolve('postcss-loader')) {
7
+ postcssLoader = {
8
+ loader: require.resolve('postcss-loader'),
10
9
  options: { sourceMap: true }
11
- }))
12
-
13
- const use = [
14
- { loader: require('mini-css-extract-plugin').loader },
15
- {
16
- loader: require.resolve('css-loader'),
17
- options: {
18
- sourceMap: true,
19
- importLoaders: 2
20
- }
21
- },
22
- tryPostcss(),
23
- ...preprocessors
24
- ].filter(Boolean)
25
-
26
- return {
27
- test,
28
- use
10
+ }
29
11
  }
12
+ } catch (e) {
13
+ /* Work out what to print here */
30
14
  }
31
15
 
32
- return null
16
+ return postcssLoader
17
+ }
18
+
19
+ const getStyleRule = (test, preprocessors = []) => {
20
+ const use = [
21
+ { loader: MiniCssExtractPlugin.loader },
22
+ {
23
+ loader: require.resolve('css-loader'),
24
+ options: {
25
+ sourceMap: true,
26
+ importLoaders: 2
27
+ }
28
+ },
29
+ tryPostcss(),
30
+ ...preprocessors
31
+ ].filter(Boolean)
32
+
33
+ return {
34
+ test,
35
+ use
36
+ }
33
37
  }
34
38
 
35
39
  module.exports = getStyleRule