From f9169d865b279493c9cb6719c3a024d268c3c367 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Sun, 21 Feb 2021 22:32:15 +0800 Subject: [PATCH] feat!: use the latest versions of css preprocessor loaders by default (#6301) --- docs/migrations/migrate-from-v4.md | 5 ++- .../@vue/cli-plugin-webpack-4/generator.js | 37 ++++++++++++++++++- packages/@vue/cli-plugin-webpack-4/index.js | 29 ++++++++++++++- .../@vue/cli-plugin-webpack-4/package.json | 3 ++ packages/@vue/cli-service/generator/index.js | 8 ++-- 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/docs/migrations/migrate-from-v4.md b/docs/migrations/migrate-from-v4.md index 5a8067d1ec..b8c4966b14 100644 --- a/docs/migrations/migrate-from-v4.md +++ b/docs/migrations/migrate-from-v4.md @@ -80,10 +80,11 @@ No longer supports generating project with `node-sass`. It has been [deprecated] * `html-webpack-plugin` is upgraded from v3 to v5, and for webpack 4 users, v4 will be used. More details are available in the [release announcement of `html-webpack-plugin` v4](https://dev.to/jantimon/html-webpack-plugin-4-has-been-released-125d) and the [full changelog](https://github.com/jantimon/html-webpack-plugin/blob/master/CHANGELOG.md). * `sass-loader` v7 support is dropped. See the v8 breaking changes at its [changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md#800-2019-08-29). -* `postcss-loader` is upgraded from v3 to v4. Most notably, `PostCSS` options (`plugin` / `syntax` / `parser` / `stringifier`) are moved into the `postcssOptions` field. More details available at the [changelog](https://github.com/webpack-contrib/postcss-loader/blob/master/CHANGELOG.md#400-2020-09-07). +* `postcss-loader` is upgraded from v3 to v5 (v4 for webpack 4 users). Most notably, `PostCSS` options (`plugin` / `syntax` / `parser` / `stringifier`) are moved into the `postcssOptions` field. More details available at the [changelog](https://github.com/webpack-contrib/postcss-loader/blob/master/CHANGELOG.md#400-2020-09-07). * `copy-webpack-plugin` is upgraded from v5 to v7 (v6 if you choose to stay at webpack 4). If you never customized its config through `config.plugin('copy')`, there should be no user-facing breaking changes. A full list of breaking changes is available at [`copy-webpack-plugin` v6.0.0 release](https://github.com/webpack-contrib/copy-webpack-plugin/releases/tag/v6.0.0) and [v7.0.0 release](https://github.com/webpack-contrib/copy-webpack-plugin/releases/tag/v7.0.0). -* `file-loader` is upgraded from v4 to v6, and `url-loader` from v2 to v4. The `esModule` option is now turned on by default for non-Vue-2 projects. Full changelog available at [`file-loader` changelog](https://github.com/webpack-contrib/file-loader/blob/master/CHANGELOG.md) and [`url-loader` changelog](https://github.com/webpack-contrib/url-loader/blob/master/CHANGELOG.md) +* `file-loader` is upgraded from v4 to v6, and `url-loader` from v2 to v4. The `esModule` option is now turned on by default for non-Vue-2 projects. Full changelog available at [`file-loader` changelog](https://github.com/webpack-contrib/file-loader/blob/master/CHANGELOG.md) and [`url-loader` changelog](https://github.com/webpack-contrib/url-loader/blob/master/CHANGELOG.md). * `terser-webpack-plugin` is upgraded from v2 to v5 (v4 if you choose to stay at webpack 4), using terser 5 and some there are some changes in the options format. See full details in its [changelog](https://github.com/webpack-contrib/terser-webpack-plugin/blob/master/CHANGELOG.md). +* When creating new projects, the default `less-loader` is updated from [v5 to v8](https://github.com/webpack-contrib/less-loader/blob/master/CHANGELOG.md)(v7 for webpack 4 users); `less` from [v3 to v4](https://github.com/less/less.js/pull/3573); `sass-loader` from [v8 to v11](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md) (v10 for webpack 4 users); `stylus-loader` from [v3 to v5](https://github.com/webpack-contrib/stylus-loader/blob/master/CHANGELOG.md) (v4 for webpack 4 users). ### ESLint Plugin diff --git a/packages/@vue/cli-plugin-webpack-4/generator.js b/packages/@vue/cli-plugin-webpack-4/generator.js index 1458a6b128..83d10e9165 100644 --- a/packages/@vue/cli-plugin-webpack-4/generator.js +++ b/packages/@vue/cli-plugin-webpack-4/generator.js @@ -1,8 +1,10 @@ +const { semver } = require('@vue/cli-shared-utils') + /** @type {import('@vue/cli').GeneratorPlugin} */ module.exports = (api) => { api.extendPackage({ devDependencies: { - 'webpack': '^4.0.0' + webpack: '^4.0.0' }, // Force resolutions is more reliable than module-alias // Yarn and PNPM 5.10+ support this feature @@ -13,5 +15,36 @@ module.exports = (api) => { } }) - // TODO: if uses sass, replace sass-loader@11 with sass-loader@10 + 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 + } + ) } diff --git a/packages/@vue/cli-plugin-webpack-4/index.js b/packages/@vue/cli-plugin-webpack-4/index.js index b238f7058e..67ea54c3db 100644 --- a/packages/@vue/cli-plugin-webpack-4/index.js +++ b/packages/@vue/cli-plugin-webpack-4/index.js @@ -10,7 +10,7 @@ const htmlWebpackPlugin4Path = path.dirname(require.resolve('html-webpack-plugin moduleAlias.addAlias('html-webpack-plugin', htmlWebpackPlugin4Path) /** @type {import('@vue/cli-service').ServicePlugin} */ -module.exports = (api, options) => { +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 @@ -49,6 +49,31 @@ module.exports = (api, options) => { .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') @@ -103,7 +128,7 @@ module.exports = (api, options) => { config.optimization.minimizer('terser').init( (Plugin, [terserPluginOptions]) => new TerserPluginV4({ - sourceMap: options.productionSourceMap, + sourceMap: rootOptions.productionSourceMap, cache: true, ...terserPluginOptions }) diff --git a/packages/@vue/cli-plugin-webpack-4/package.json b/packages/@vue/cli-plugin-webpack-4/package.json index dca10b84b8..658236a48f 100644 --- a/packages/@vue/cli-plugin-webpack-4/package.json +++ b/packages/@vue/cli-plugin-webpack-4/package.json @@ -23,11 +23,14 @@ "access": "public" }, "dependencies": { + "@vue/cli-shared-utils": "^5.0.0-alpha.4", "copy-webpack-plugin": "^6.4.1", "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" }, diff --git a/packages/@vue/cli-service/generator/index.js b/packages/@vue/cli-service/generator/index.js index 24cb2f74ff..c2a9f8edbd 100644 --- a/packages/@vue/cli-service/generator/index.js +++ b/packages/@vue/cli-service/generator/index.js @@ -39,19 +39,19 @@ module.exports = (api, options) => { const deps = { sass: { sass: '^1.32.7', - 'sass-loader': '^10.1.0' + 'sass-loader': '^11.0.1' }, 'dart-sass': { sass: '^1.32.7', 'sass-loader': '^10.1.0' }, less: { - 'less': '^3.0.4', - 'less-loader': '^5.0.0' + 'less': '^4.0.0', + 'less-loader': '^8.0.0' }, stylus: { 'stylus': '^0.54.8', - 'stylus-loader': '^4.3.1' + 'stylus-loader': '^5.0.0' } }