diff --git a/.circleci/config.yml b/.circleci/config.yml index e99848fb7a..aa8b4bbf10 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,13 +49,6 @@ jobs: at: ~/ - run: yarn test -p cli,cli-service,cli-shared-utils - core-webpack-4: - <<: *defaults - steps: - - attach_workspace: - at: ~/ - - run: VUE_CLI_USE_WEBPACK4=true yarn test -p cli,cli-service,cli-shared-utils - typescript: <<: *defaults steps: @@ -63,13 +56,6 @@ jobs: at: ~/ - run: yarn test 'ts(?:\w(?!E2e))+\.spec\.js$' - typescript-webpack-4: - <<: *defaults - steps: - - attach_workspace: - at: ~/ - - run: VUE_CLI_USE_WEBPACK4=true yarn test 'ts(?:\w(?!E2e))+\.spec\.js$' - plugins: <<: *defaults steps: @@ -79,13 +65,6 @@ jobs: - run: yarn check-links - run: yarn test -p eslint,pwa,babel,babel-preset-app,vuex,router - plugins-webpack-4: - <<: *defaults - steps: - - attach_workspace: - at: ~/ - - run: VUE_CLI_USE_WEBPACK4=true yarn test -p eslint,pwa,babel,babel-preset-app,vuex,router - tests: <<: *defaults steps: @@ -95,14 +74,6 @@ jobs: # e2e-nightwatch was left out due to some unknown issues with selenium and the CI image - run: yarn test tsPluginE2e - tests-webpack-4: - <<: *defaults - steps: - - attach_workspace: - at: ~/ - - run: VUE_CLI_USE_WEBPACK4=true yarn test -p unit-mocha,unit-jest,e2e-cypress - - run: VUE_CLI_USE_WEBPACK4=true yarn test tsPluginE2e - cli-ui: <<: *defaults steps: @@ -116,8 +87,6 @@ jobs: - store_artifacts: path: /home/circleci/.npm/_logs - # TODO: cli-ui-webpack-4 - workflows: version: 2 test: @@ -128,34 +97,18 @@ workflows: <<: *filters requires: - install - - core-webpack-4: - <<: *filters - requires: - - install - typescript: <<: *filters requires: - install - - typescript-webpack-4: - <<: *filters - requires: - - install - plugins: <<: *filters requires: - install - - plugins-webpack-4: - <<: *filters - requires: - - install - tests: <<: *filters requires: - install - - tests-webpack-4: - <<: *filters - requires: - - install - cli-ui: <<: *filters requires: diff --git a/docs/core-plugins/webpack-4.md b/docs/core-plugins/webpack-4.md deleted file mode 100644 index eceaf75ea6..0000000000 --- a/docs/core-plugins/webpack-4.md +++ /dev/null @@ -1,3 +0,0 @@ -# @vue/cli-plugin-webpack-4 - -This plugin provides compatibily for webpack 4 in Vue CLI 5. diff --git a/docs/migrations/migrate-from-v4.md b/docs/migrations/migrate-from-v4.md index 837a125c74..88a99dfce1 100644 --- a/docs/migrations/migrate-from-v4.md +++ b/docs/migrations/migrate-from-v4.md @@ -60,22 +60,6 @@ Besides the internal changes that are only noticeable for custom configurations, 1. Named exports from JSON modules are no longer supported. Instead of `import { version } from './package.json'; console.log(version);` use `import package from './package.json'; console.log(package.version);` 2. Webpack 5 does no longer include polyfills for Node.js modules by default. You shall see an informative error message if your code relies on any of these modules. A detailed list of previously polyfilled modules is also available [here](https://github.com/webpack/webpack/pull/8460/commits/a68426e9255edcce7822480b78416837617ab065). -#### Opt Out to Webpack 4 - -Considering many ecosystem packages haven't catched up yet, we provided a plugin to opt out to webpack 4 for easier migration. - -It's as simple as running - -```sh -vue add webpack-4 -``` - -at the project root. - -Underlyingly, it uses the [`resolutions`](https://classic.yarnpkg.com/en/docs/selective-version-resolutions) field for Yarn and PNPM users, and [`module-alias`](https://github.com/ilearnio/module-alias) for NPM users. - -Though both work in all our tests, please be aware that the `module-alias` approach is still considered hacky, and may not be as stable as the `"resolutions"` one. - #### Changes to the `build` command and modern mode Starting with v5.0.0-beta.0, running `vue-cli-service build` will automatically generate different bundles based on your browserslist configurations. diff --git a/jest.config.js b/jest.config.js index 33dfde8250..bfc9df2757 100644 --- a/jest.config.js +++ b/jest.config.js @@ -7,10 +7,3 @@ module.exports = { '**/__tests__/**/*.spec.js' ] } - -if (process.env.VUE_CLI_USE_WEBPACK4) { - module.exports.moduleNameMapper = { - '^webpack$': 'webpack-4', - '^webpack/(.*)': 'webpack-4/$1' - } -} diff --git a/packages/@vue/cli-plugin-webpack-4/README.md b/packages/@vue/cli-plugin-webpack-4/README.md deleted file mode 100644 index eceaf75ea6..0000000000 --- a/packages/@vue/cli-plugin-webpack-4/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @vue/cli-plugin-webpack-4 - -This plugin provides compatibily for webpack 4 in Vue CLI 5. diff --git a/packages/@vue/cli-plugin-webpack-4/generator.js b/packages/@vue/cli-plugin-webpack-4/generator.js deleted file mode 100644 index ae0ea29973..0000000000 --- a/packages/@vue/cli-plugin-webpack-4/generator.js +++ /dev/null @@ -1,51 +0,0 @@ -const { semver } = require('@vue/cli-shared-utils') - -/** @type {import('@vue/cli').GeneratorPlugin} */ -module.exports = (api) => { - api.extendPackage({ - devDependencies: { - webpack: '^4.0.0' - }, - // Force resolutions is more reliable than module-alias - // Yarn and PNPM 5.10+ support this feature - // So we'll try to use that whenever possible - resolutions: { - '@vue/cli-*/webpack': '^4.0.0', - 'html-webpack-plugin': '^4.5.1' - } - }) - - api.extendPackage( - (pkg) => { - const oldDevDeps = pkg.devDependencies - const newDevDeps = {} - const unsupportedRanges = { - 'less-loader': '>= 8.0.0', - 'sass-loader': '>= 11.0.0', - 'stylus-loader': '>= 5.0.0' - } - const maxSupportedRanges = { - 'less-loader': '^7.3.0', - 'sass-loader': '^10.1.1', - 'stylus-loader': '^4.3.3' - } - - for (const loader of ['less-loader', 'sass-loader', 'stylus-loader']) { - if ( - oldDevDeps[loader] && - semver.intersects(oldDevDeps[loader], unsupportedRanges[loader]) - ) { - newDevDeps[loader] = maxSupportedRanges[loader] - } - } - - const toMerge = { devDependencies: newDevDeps } - - return toMerge - }, - { - warnIncompatibleVersions: false, - forceOverwrite: true - } - ) -} diff --git a/packages/@vue/cli-plugin-webpack-4/index.js b/packages/@vue/cli-plugin-webpack-4/index.js deleted file mode 100644 index 3142eb873d..0000000000 --- a/packages/@vue/cli-plugin-webpack-4/index.js +++ /dev/null @@ -1,158 +0,0 @@ -const fs = require('fs') -const path = require('path') -const moduleAlias = require('module-alias') - -const htmlWebpackPlugin4Path = path.dirname(require.resolve('html-webpack-plugin/package.json')) -// We have to use module-alias for html-webpack-plguin, as it is required by many other plugins -// as peer dependency for its `getHooks` API. -// Should add the alias as early as possible to avoid problems -// TODO: add debugging log here -moduleAlias.addAlias('html-webpack-plugin', htmlWebpackPlugin4Path) - -/** @type {import('@vue/cli-service').ServicePlugin} */ -module.exports = (api, rootOptions) => { - api.chainWebpack(config => { - // webpack-4 alias is set for the webpack-dev-server - // should also set for the injected client hmr code so as to avoid mismatch - const webpack4Path = path.dirname(require.resolve('webpack/package.json')) - config.resolve.alias.set('webpack', webpack4Path) - - // Node.js polyfills - // They are not polyfilled by default in webpack 5 - // - // In webpack 4, we used to disabled many of the core module polyfills too - config.node - .merge({ - // prevent webpack from injecting useless setImmediate polyfill because Vue - // source contains it (although only uses it if it's native). - setImmediate: false, - // process is injected via DefinePlugin, although some 3rd party - // libraries may require a mock to work properly (#934) - process: 'mock', - // prevent webpack from injecting mocks to Node native modules - // that does not make sense for the client - dgram: 'empty', - fs: 'empty', - net: 'empty', - tls: 'empty', - child_process: 'empty' - }) - - // Yarn PnP / Yarn 2 support - config.resolve - .plugin('pnp') - .use({ ...require('pnp-webpack-plugin') }) - .end() - - config.resolveLoader - .plugin('pnp-loaders') - .use({ ...require('pnp-webpack-plugin').topLevelLoader }) - .end() - - // Use postcss-loader v7 - const shadowMode = !!process.env.VUE_CLI_CSS_SHADOW_MODE - const isProd = process.env.NODE_ENV === 'production' - const { extract = isProd } = rootOptions.css || {} - const shouldExtract = extract !== false && !shadowMode - const needInlineMinification = isProd && !shouldExtract - - const postcssLoaderPath = require.resolve('postcss-loader') - - const langs = ['css', 'postcss', 'scss', 'sass', 'less', 'stylus'] - const matches = ['vue-modules', 'vue', 'normal-modules', 'normal'] - - langs.forEach(lang => - matches.forEach(match => { - const rule = config.module - .rule(lang) - .oneOf(match) - - if (needInlineMinification) { - rule.use('cssnano').loader(postcssLoaderPath) - } - rule.use('postcss-loader').loader(postcssLoaderPath) - }) - ) - - if (!process.env.VUE_CLI_BUILD_TARGET || process.env.VUE_CLI_BUILD_TARGET === 'app') { - const isLegacyBundle = process.env.VUE_CLI_MODERN_MODE && !process.env.VUE_CLI_MODERN_BUILD - const publicDir = api.resolve('public') - if (!isLegacyBundle && fs.existsSync(publicDir)) { - const CopyWebpackPluginV6 = require('copy-webpack-plugin') - config - .plugin('copy') - .init((Plugin, args) => new CopyWebpackPluginV6(...args)) - } - - if (process.env.NODE_ENV === 'production') { - // In webpack 5, optimization.chunkIds is set to `deterministic` by default in production - // In webpack 4, we use the following trick to keep chunk ids stable so async chunks have consistent hash (#1916) - config - .plugin('named-chunks') - .use(require('webpack').NamedChunksPlugin, [chunk => { - if (chunk.name) { - return chunk.name - } - - const hash = require('hash-sum') - const joinedHash = hash( - Array.from(chunk.modulesIterable, m => m.id).join('_') - ) - return `chunk-` + joinedHash - }]) - } - - if (process.env.NODE_ENV !== 'test') { - config.optimization.splitChunks({ - cacheGroups: { - vendors: { - name: `chunk-vendors`, - test: /[\\/]node_modules[\\/]/, - priority: -10, - chunks: 'initial' - }, - common: { - name: `chunk-common`, - minChunks: 2, - priority: -20, - chunks: 'initial', - reuseExistingChunk: true - } - } - }) - } - } - - if (process.env.NODE_ENV === 'production') { - const TerserPluginV4 = require('terser-webpack-plugin') - config.optimization.minimizer('terser').init( - (Plugin, [terserPluginOptions]) => - new TerserPluginV4({ - sourceMap: rootOptions.productionSourceMap, - cache: true, - ...terserPluginOptions - }) - ) - - if (shouldExtract) { - const CssMinimizerPluginV1 = require('css-minimizer-webpack-plugin') - config.optimization.minimizer('css').init( - (Plugin, [cssMinimizerOptions]) => - new CssMinimizerPluginV1({ - sourceMap: rootOptions.productionSourceMap, - ...cssMinimizerOptions - }) - ) - } - - // DeterministicModuleIdsPlugin is only available in webpack 5 - // (and enabled by default in production mode). - - // In webpack 4, we need HashedModuleIdsPlugin - // to keep module.id stable when vendor modules does not change. - // It is "the second best solution for long term caching". - // - config.optimization.set('hashedModuleIds', true) - } - }) -} diff --git a/packages/@vue/cli-plugin-webpack-4/package.json b/packages/@vue/cli-plugin-webpack-4/package.json deleted file mode 100644 index a90732a0f4..0000000000 --- a/packages/@vue/cli-plugin-webpack-4/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "@vue/cli-plugin-webpack-4", - "version": "5.0.0-beta.2", - "description": "webpack-4 plugin for @vue/cli v5", - "main": "index.js", - "repository": { - "type": "git", - "url": "git+https://github.com/vuejs/vue-cli.git", - "directory": "packages/@vue/cli-plugin-webpack-4" - }, - "keywords": [ - "vue", - "cli", - "webpack 4" - ], - "author": "Haoqun Jiang", - "license": "MIT", - "bugs": { - "url": "https://github.com/vuejs/vue-cli/issues" - }, - "homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/@vue/cli-plugin-webpack-4#readme", - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@vue/cli-shared-utils": "^5.0.0-beta.2", - "copy-webpack-plugin": "^6.4.1", - "css-minimizer-webpack-plugin": "^1.2.0", - "hash-sum": "^2.0.0", - "html-webpack-plugin": "^4.5.1", - "module-alias": "^2.2.2", - "pnp-webpack-plugin": "^1.6.4", - "postcss": "^8.2.6", - "postcss-loader": "^4.2.0", - "terser-webpack-plugin": "^4.2.3", - "webpack": "^4.44.2" - }, - "peerDependencies": { - "@vue/cli-service": "^5.0.0-0" - } -} diff --git a/packages/@vue/cli-service/lib/Service.js b/packages/@vue/cli-service/lib/Service.js index 82d6c58aaa..65e06d0855 100644 --- a/packages/@vue/cli-service/lib/Service.js +++ b/packages/@vue/cli-service/lib/Service.js @@ -9,7 +9,6 @@ const defaultsDeep = require('lodash.defaultsdeep') const { warn, error, isPlugin, resolvePluginId, loadModule, resolvePkg, resolveModule, sortPlugins } = require('@vue/cli-shared-utils') const { defaults } = require('./options') -const checkWebpack = require('./util/checkWebpack') const loadFileConfig = require('./util/loadFileConfig') const resolveUserConfig = require('./util/resolveUserConfig') @@ -17,8 +16,6 @@ const resolveUserConfig = require('./util/resolveUserConfig') const isPromise = p => p && typeof p.then === 'function' module.exports = class Service { constructor (context, { plugins, pkg, inlineOptions, useBuiltIn } = {}) { - checkWebpack(context) - process.VUE_CLI_SERVICE = this this.initialized = false this.context = context @@ -199,17 +196,6 @@ module.exports = class Service { } }) - // Add the plugin automatically to simplify the webpack-4 tests - // so that a simple Jest alias would suffice, avoid changing every - // preset used in the tests - if ( - process.env.VUE_CLI_TEST && - process.env.VUE_CLI_USE_WEBPACK4 && - !projectPlugins.some((p) => p.id === '@vue/cli-plugin-webpack-4') - ) { - builtInPlugins.push(idToPlugin('@vue/cli-plugin-webpack-4')) - } - plugins = builtInPlugins.concat(projectPlugins) } diff --git a/packages/@vue/cli-service/lib/util/checkWebpack.js b/packages/@vue/cli-service/lib/util/checkWebpack.js deleted file mode 100644 index f9d42eba4d..0000000000 --- a/packages/@vue/cli-service/lib/util/checkWebpack.js +++ /dev/null @@ -1,55 +0,0 @@ -const path = require('path') -const { warn, loadModule, resolveModule } = require('@vue/cli-shared-utils') -const moduleAlias = require('module-alias') - -/** - * If the user has installed a version of webpack themself, load it. - * Otherwise, load the webpack that @vue/cli-service depends on. - * @param {string} cwd the user project root - * @returns {import('webpack')} note: the return type is for webpack 5 only - */ -module.exports = function checkWebpack (cwd) { - // Jest module alias can't affect sub-processes, so we have to alias it manually - if ( - process.env.VUE_CLI_TEST && - process.env.VUE_CLI_USE_WEBPACK4 && - require('webpack/package.json').version[0] !== '4' - ) { - const webpack4Path = path.dirname(require.resolve('webpack-4/package.json')) - moduleAlias.addAlias('webpack', webpack4Path) - - return - } - - // Check the package.json, - // and only load from the project if webpack is explictly depended on, - // in case of accidental hoisting. - - let pkg = {} - try { - pkg = loadModule('./package.json', cwd) - } catch (e) {} - - const deps = { - ...pkg.dependencies, - ...pkg.devDependencies, - ...pkg.optionalDependencies - } - - if (deps.webpack) { - const customWebpackVersion = loadModule('webpack/package.json', cwd).version - const requiredWebpackVersion = require('webpack/package.json').version - - // A custom webpack version is found but no force resolutions used. - // So the webpack version in this package is still 5.x. - // This may cause problems for loaders/plugins required in this package. - // Because many uses runtime sniffing to run conditional code for different webpack versions. - if (customWebpackVersion !== requiredWebpackVersion) { - // TODO: recommend users to use yarn force resolutions or pnpm hooks instead - warn(`Using "module-alias" to load custom webpack version.`) - - const webpack4Path = path.dirname(resolveModule('webpack/package.json', cwd)) - moduleAlias.addAlias('webpack', webpack4Path) - } - } -} diff --git a/packages/@vue/cli-service/package.json b/packages/@vue/cli-service/package.json index 724e2e35ce..f29c92ba1e 100644 --- a/packages/@vue/cli-service/package.json +++ b/packages/@vue/cli-service/package.json @@ -120,8 +120,7 @@ "vue": "^2.6.12", "vue-router": "^3.5.1", "vue-template-compiler": "^2.6.12", - "vuex": "^3.6.2", - "webpack-4": "npm:webpack@^4.44.2" + "vuex": "^3.6.2" }, "publishConfig": { "access": "public" diff --git a/scripts/test.js b/scripts/test.js index 0a6c0a8f81..abe6082514 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -10,7 +10,7 @@ if (args.p) { rawArgs.splice(i, 2) } -const e2ePathPattern = 'Migrator|Vue3|mochaPlugin|MochaPlugin|cli-plugin-webpack-4' +const e2ePathPattern = 'Migrator|Vue3|mochaPlugin|MochaPlugin' if (args['e2e-only']) { regex = e2ePathPattern