webpacker 6.0.0.beta.6 → 6.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
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