diff --git a/packages/vue-cli-plugin-uni/commands/build.js b/packages/vue-cli-plugin-uni/commands/build.js index cad7e5941465d2118a24ec8eb820f8a9f8920d5e..9744264cfeeb4a94dfc27dfc5da69ab758ab5c98 100644 --- a/packages/vue-cli-plugin-uni/commands/build.js +++ b/packages/vue-cli-plugin-uni/commands/build.js @@ -1,4 +1,5 @@ const path = require('path') +const webpack = require('webpack') const { runByHBuilderX, @@ -98,14 +99,18 @@ function getWebpackConfig (api, args, options) { if (args.minimize && process.env.NODE_ENV !== 'production') { modifyConfig(webpackConfig, config => { config.optimization.minimize = true + if (webpack.version[0] <= 4) { config.optimization.namedModules = false + } }) } else { modifyConfig(webpackConfig, config => { if (!config.optimization) { config.optimization = {} } + if (webpack.version[0] <= 4) { config.optimization.namedModules = false + } }) } return webpackConfig @@ -131,7 +136,6 @@ function getWebpackConfigs (api, args, options) { async function build (args, api, options) { const fs = require('fs-extra') const chalk = require('chalk') - const webpack = require('webpack') const { log, diff --git a/packages/vue-cli-plugin-uni/commands/serve.js b/packages/vue-cli-plugin-uni/commands/serve.js index 3a2d36d560236efa59c48d44a9f9bf0d5c571276..b2d04db4a9d9ca4a305dcac24405f7f39e8859ee 100644 --- a/packages/vue-cli-plugin-uni/commands/serve.js +++ b/packages/vue-cli-plugin-uni/commands/serve.js @@ -37,7 +37,7 @@ module.exports = (api, options) => { const url = require('url') const path = require('path') - const chalk = require('chalk') + const { chalk } = require('@vue/cli-shared-utils') const webpack = require('webpack') const WebpackDevServer = require('webpack-dev-server') const portfinder = require('portfinder') @@ -139,7 +139,56 @@ module.exports = (api, options) => { const compiler = webpack(webpackConfig) // create server - const server = new WebpackDevServer(compiler, Object.assign({ + let server + if (webpack.version[0] > 4) { + server = new WebpackDevServer(Object.assign({ + historyApiFallback: { + disableDotRule: true, + rewrites: [{ + from: /./, + to: path.posix.join(options.publicPath, 'index.html') + }] + }, + hot: !isProduction, + compress: isProduction, + static: { + directory: api.resolve('public'), + publicPath: options.publicPath, + watch: !isProduction, + ...projectDevServerOptions.static + }, + client: { + logging: 'none', + overlay: isProduction // TODO disable this + ? false + : { warnings: false, errors: true }, + progress: !process.env.VUE_CLI_TEST, + ...projectDevServerOptions.client + } + }, projectDevServerOptions, { + https: useHttps, + proxy: proxySettings, + setupMiddlewares (middlewares, devServer) { + // launch editor support. + // this works with vue-devtools & @vue/cli-overlay + devServer.app.use('/__open-in-editor', launchEditorMiddleware(() => console.log( + `To specify an editor, specify the EDITOR env variable or ` + + `add "editor" field to your Vue project config.\n` + ))) + + // allow other plugins to register middlewares, e.g. PWA + // todo: migrate to the new API interface + api.service.devServerConfigFns.forEach(fn => fn(devServer.app, devServer)) + + if (projectDevServerOptions.setupMiddlewares) { + return projectDevServerOptions.setupMiddlewares(middlewares, devServer) + } + + return middlewares + } + }), compiler) + } else { + server = new WebpackDevServer(compiler, Object.assign({ clientLogLevel: 'none', historyApiFallback: { disableDotRule: true, @@ -176,11 +225,12 @@ module.exports = (api, options) => { server) } })) + } ; ['SIGINT', 'SIGTERM'].forEach(signal => { process.on(signal, () => { - server.close(() => { + server[webpack.version[0] > 4 ? 'stopCallback' : 'close'](() => { process.exit(0) }) }) @@ -192,7 +242,7 @@ module.exports = (api, options) => { process.stdin.on('data', data => { if (data.toString() === 'close') { console.log('got close signal!') - server.close(() => { + server[webpack.version[0] > 4 ? 'stopCallback' : 'close'](() => { process.exit(0) }) } @@ -303,11 +353,15 @@ module.exports = (api, options) => { server.showStatus = function () {} } + if (webpack.version[0] > 4) { + server.start().catch(err => reject(err)) + } else { server.listen(port, host, err => { if (err) { reject(err) } }) + } }) }) } diff --git a/packages/vue-cli-plugin-uni/lib/app-plus/index.js b/packages/vue-cli-plugin-uni/lib/app-plus/index.js index 99193bbe04ace95defe0d9e74a7a4838e7c86464..2cd3a4f518e94eed7c0b7ae84f4107438be973d2 100644 --- a/packages/vue-cli-plugin-uni/lib/app-plus/index.js +++ b/packages/vue-cli-plugin-uni/lib/app-plus/index.js @@ -70,7 +70,11 @@ const v3 = { webpackConfig.optimization = {} } // disable noEmitOnErrors - webpackConfig.optimization.noEmitOnErrors = false + if (webpack.version[0] > 4) { + webpackConfig.optimization.emitOnErrors = true + } else { + webpackConfig.optimization.noEmitOnErrors = false + } if (isAppService) { webpackConfig.optimization.runtimeChunk = { @@ -134,7 +138,8 @@ const v3 = { output: { filename: '[name].js', chunkFilename: '[id].js', - globalObject: 'this' + // webpack5 use strict + globalObject: webpack.version[0] > 4 ? `(new Function("return this")())` : 'this' }, performance: { hints: false @@ -158,7 +163,7 @@ const v3 = { compiler: vueLoader.compiler, before: [ beforeCode + require('../util').getAutomatorCode() + statCode + pushCode + uniCloudCode + - getGlobalUsingComponentsCode() + getGlobalUsingComponentsCode() ] } }] diff --git a/packages/vue-cli-plugin-uni/lib/chain-webpack.js b/packages/vue-cli-plugin-uni/lib/chain-webpack.js index 038402d71f470348ffc9f05fdf368afc02c29064..bfca415581e3d9351b9951f32dee2e5bf79520b0 100644 --- a/packages/vue-cli-plugin-uni/lib/chain-webpack.js +++ b/packages/vue-cli-plugin-uni/lib/chain-webpack.js @@ -1,4 +1,5 @@ const path = require('path') +const webpack = require('webpack') const { sassLoaderVersion @@ -23,11 +24,22 @@ module.exports = function chainWebpack (platformOptions, vueOptions, api) { const urlLoader = require('@dcloudio/uni-cli-shared/lib/url-loader') const staticTypes = ['images', 'media', 'fonts'] staticTypes.forEach(staticType => { - webpackConfig.module - .rule(staticType) - .use('url-loader') - .loader(urlLoader.loader) - .tap(options => Object.assign(options, urlLoader.options())) + const newOptions = urlLoader.options() + if (webpack.version[0] > 4) { + if ('limit' in newOptions) { + webpackConfig.module.rule(staticType).parser({ + dataUrlCondition: { + maxSize: newOptions.limit + } + }) + } + } else { + webpackConfig.module + .rule(staticType) + .use('url-loader') + .loader(urlLoader.loader) + .tap(options => Object.assign(options, newOptions)) + } }) // 条件编译 vue 文件统一直接过滤html,js,css三种类型,单独资源文件引用各自过滤 diff --git a/packages/vue-cli-plugin-uni/lib/configure-webpack.js b/packages/vue-cli-plugin-uni/lib/configure-webpack.js index c71ec2b69fc074946eed4741098f9af9e42aac75..9ddf81b1ec0202feecc664df9443a7c45c003104 100644 --- a/packages/vue-cli-plugin-uni/lib/configure-webpack.js +++ b/packages/vue-cli-plugin-uni/lib/configure-webpack.js @@ -1,7 +1,6 @@ const fs = require('fs') const path = require('path') const webpack = require('webpack') -const RuleSet = require('webpack/lib/RuleSet') const CopyWebpackPlugin = require('copy-webpack-plugin') const merge = require('webpack-merge') @@ -39,6 +38,37 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt return (rule, i) => { const clone = Object.assign({}, rule) delete clone.include + if (webpack.version[0] > 4) { + const BasicEffectRulePlugin = require('webpack/lib/rules/BasicEffectRulePlugin') + const BasicMatcherRulePlugin = require('webpack/lib/rules/BasicMatcherRulePlugin') + const RuleSetCompiler = require('webpack/lib/rules/RuleSetCompiler') + const UseEffectRulePlugin = require('webpack/lib/rules/UseEffectRulePlugin') + const ruleSetCompiler = new RuleSetCompiler([ + new BasicMatcherRulePlugin('test', 'resource'), + new BasicMatcherRulePlugin('include', 'resource'), + new BasicMatcherRulePlugin('exclude', 'resource', true), + new BasicMatcherRulePlugin('resource'), + new BasicMatcherRulePlugin('conditions'), + new BasicMatcherRulePlugin('resourceQuery'), + new BasicMatcherRulePlugin('realResource'), + new BasicMatcherRulePlugin('issuer'), + new BasicMatcherRulePlugin('compiler'), + new BasicEffectRulePlugin('type'), + new BasicEffectRulePlugin('sideEffects'), + new BasicEffectRulePlugin('parser'), + new BasicEffectRulePlugin('resolve'), + new BasicEffectRulePlugin('generator'), + new UseEffectRulePlugin() + ]) + const ruleSet = ruleSetCompiler.compile([{ + rules: [clone] + }]) + const rules = ruleSet.exec({ + resource: fakeFile + }) + return rules.length > 0 && rule.use + } else { + const RuleSet = require('webpack/lib/RuleSet') const normalized = RuleSet.normalizeRule(clone, {}, '') return ( !rule.enforce && @@ -47,6 +77,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt ) } } + } function updateJsLoader (rawRules, fakeFile, checkLoaderRegex, loader) { const matchRule = rawRules.find(createMatcher(fakeFile)) @@ -152,6 +183,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt if (Array.isArray(uses)) { if (uses.find(use => babelLoaderRe.test(use.loader))) { const index = uses.findIndex(use => cacheLoaderRe.test(use.loader)) + if (index >= 0) { if (process.env.UNI_USING_CACHE) { Object.assign(uses[index].options, api.genCacheConfig( 'babel-loader/' + process.env.UNI_PLATFORM, @@ -163,6 +195,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt } } } + } // js preprocess updateJsLoader(rawRules, 'foo.js', babelLoaderRe, { diff --git a/packages/vue-cli-plugin-uni/lib/h5/cssnano-options.js b/packages/vue-cli-plugin-uni/lib/h5/cssnano-options.js index 5428a35896d8db2801ad35d8d65b6f9bb0eb6fe8..8a783f9ae51daae4fa1450127f0af0db434cd681 100644 --- a/packages/vue-cli-plugin-uni/lib/h5/cssnano-options.js +++ b/packages/vue-cli-plugin-uni/lib/h5/cssnano-options.js @@ -1,15 +1,24 @@ const { getPlatformCssnano } = require('@dcloudio/uni-cli-shared') +const webpack = require('webpack') module.exports = function initCssnanoOptions (webpackConfig) { const module = webpackConfig.module // TODO 临时 hack calc:false 看看 vue cli 后续是否开放 cssnano 的配置 const cssnanoOptions = { - sourceMap: false, - plugins: [require('cssnano')({ + sourceMap: false + } + + const plugins = [require('cssnano')({ preset: ['default', getPlatformCssnano()] })] + + // TODO postcss-loader version > 4 + if (webpack.version[0] > 4) { + cssnanoOptions.postcssOptions = { plugins } + } else { + cssnanoOptions.plugins = plugins } module.rule('css').oneOf('vue-modules').use('cssnano').loader('postcss-loader').options(cssnanoOptions) diff --git a/packages/vue-cli-plugin-uni/lib/h5/index.js b/packages/vue-cli-plugin-uni/lib/h5/index.js index e6ec19eb19c5e1247e72298257b5fb7381c5de55..d0d621ba7dffdc612fb12583e6f201d6e0d26e47 100644 --- a/packages/vue-cli-plugin-uni/lib/h5/index.js +++ b/packages/vue-cli-plugin-uni/lib/h5/index.js @@ -160,9 +160,13 @@ module.exports = { }, plugins, optimization: { - moduleIds: 'hashed' + moduleIds: webpack.version[0] > 4 ? 'deterministic' : 'hashed' }, - devServer: { + devServer: webpack.version[0] > 4 ? { + watchFiles: { + options: require('../util').getWatchOptions() + } + } : { watchOptions: require('../util').getWatchOptions() } } diff --git a/packages/vue-cli-plugin-uni/lib/mp/index.js b/packages/vue-cli-plugin-uni/lib/mp/index.js index e145332500562d894e4c783cac17dfd0496fcf93..ffcb975d0833d8deb261a42cf73b9afb86c6904e 100644 --- a/packages/vue-cli-plugin-uni/lib/mp/index.js +++ b/packages/vue-cli-plugin-uni/lib/mp/index.js @@ -157,7 +157,11 @@ module.exports = { webpackConfig.optimization = {} } // disable noEmitOnErrors - webpackConfig.optimization.noEmitOnErrors = false + if (webpack.version[0] > 4) { + webpackConfig.optimization.emitOnErrors = true + } else { + webpackConfig.optimization.noEmitOnErrors = false + } webpackConfig.optimization.runtimeChunk = { name: 'common/runtime' diff --git a/packages/vue-cli-plugin-uni/lib/options.js b/packages/vue-cli-plugin-uni/lib/options.js index 27cab09c1669bcf106567d4116024f8fca9a5a86..25ef468a8511efa098d2fb9a1798a46905ae2629 100644 --- a/packages/vue-cli-plugin-uni/lib/options.js +++ b/packages/vue-cli-plugin-uni/lib/options.js @@ -1,5 +1,6 @@ const fs = require('fs') const path = require('path') +const webpack = require('webpack') const isWin = /^win/.test(process.platform) @@ -23,11 +24,11 @@ module.exports = function initOptions (options) { options.transpileDependencies.push(genTranspileDepRegex(path.resolve(process.env.UNI_INPUT_DIR, 'node_modules'))) options.transpileDependencies.push('@dcloudio/uni-' + process.env.UNI_PLATFORM) options.transpileDependencies.push('@dcloudio/uni-i18n') - options.transpileDependencies.push('@dcloudio/uni-stat') + options.transpileDependencies.push('@dcloudio/uni-stat') options.transpileDependencies.push('@dcloudio/uni-push') options.transpileDependencies.push('@dcloudio/vue-cli-plugin-uni/packages/uni-app') options.transpileDependencies.push('@dcloudio/vue-cli-plugin-uni/packages/uni-cloud') - options.transpileDependencies.push('@dcloudio/vue-cli-plugin-uni/packages/uni-stat') + options.transpileDependencies.push('@dcloudio/vue-cli-plugin-uni/packages/uni-stat') options.transpileDependencies.push('@dcloudio/vue-cli-plugin-uni/packages/uni-push') if (process.env.UNI_PLATFORM !== 'mp-weixin') { // mp runtime @@ -59,8 +60,14 @@ module.exports = function initOptions (options) { options.css.loaderOptions.sass = {} } - if (!options.css.loaderOptions.postcss.config) { - options.css.loaderOptions.postcss.config = {} + if (webpack.version[0] > 4) { + if (!options.css.loaderOptions.postcss.postcssOptions) { + options.css.loaderOptions.postcss.postcssOptions = {} + } + } else { + if (!options.css.loaderOptions.postcss.config) { + options.css.loaderOptions.postcss.config = {} + } } // sass 全局变量 @@ -85,9 +92,10 @@ module.exports = function initOptions (options) { } options.css.loaderOptions.sass.prependData = sassData const userPostcssConfigPath = path.resolve(process.env.UNI_INPUT_DIR, 'postcss.config.js') - if (fs.existsSync(userPostcssConfigPath)) { - options.css.loaderOptions.postcss.config.path = userPostcssConfigPath + const configPath = fs.existsSync(userPostcssConfigPath) ? userPostcssConfigPath : path.resolve(process.env.UNI_CLI_CONTEXT, 'postcss.config.js') + if (webpack.version[0] > 4) { + options.css.loaderOptions.postcss.postcssOptions.config = configPath } else { - options.css.loaderOptions.postcss.config.path = path.resolve(process.env.UNI_CLI_CONTEXT, 'postcss.config.js') + options.css.loaderOptions.postcss.config.path = configPath } -} +}