提交 e3800009 编写于 作者: Q qiang

feat(vue-cli-plugin-uni): support webpack5

上级 05275209
const path = require('path') const path = require('path')
const webpack = require('webpack')
const { const {
runByHBuilderX, runByHBuilderX,
...@@ -98,14 +99,18 @@ function getWebpackConfig (api, args, options) { ...@@ -98,14 +99,18 @@ function getWebpackConfig (api, args, options) {
if (args.minimize && process.env.NODE_ENV !== 'production') { if (args.minimize && process.env.NODE_ENV !== 'production') {
modifyConfig(webpackConfig, config => { modifyConfig(webpackConfig, config => {
config.optimization.minimize = true config.optimization.minimize = true
if (webpack.version[0] <= 4) {
config.optimization.namedModules = false config.optimization.namedModules = false
}
}) })
} else { } else {
modifyConfig(webpackConfig, config => { modifyConfig(webpackConfig, config => {
if (!config.optimization) { if (!config.optimization) {
config.optimization = {} config.optimization = {}
} }
if (webpack.version[0] <= 4) {
config.optimization.namedModules = false config.optimization.namedModules = false
}
}) })
} }
return webpackConfig return webpackConfig
...@@ -131,7 +136,6 @@ function getWebpackConfigs (api, args, options) { ...@@ -131,7 +136,6 @@ function getWebpackConfigs (api, args, options) {
async function build (args, api, options) { async function build (args, api, options) {
const fs = require('fs-extra') const fs = require('fs-extra')
const chalk = require('chalk') const chalk = require('chalk')
const webpack = require('webpack')
const { const {
log, log,
......
...@@ -37,7 +37,7 @@ module.exports = (api, options) => { ...@@ -37,7 +37,7 @@ module.exports = (api, options) => {
const url = require('url') const url = require('url')
const path = require('path') const path = require('path')
const chalk = require('chalk') const { chalk } = require('@vue/cli-shared-utils')
const webpack = require('webpack') const webpack = require('webpack')
const WebpackDevServer = require('webpack-dev-server') const WebpackDevServer = require('webpack-dev-server')
const portfinder = require('portfinder') const portfinder = require('portfinder')
...@@ -139,7 +139,56 @@ module.exports = (api, options) => { ...@@ -139,7 +139,56 @@ module.exports = (api, options) => {
const compiler = webpack(webpackConfig) const compiler = webpack(webpackConfig)
// create server // 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', clientLogLevel: 'none',
historyApiFallback: { historyApiFallback: {
disableDotRule: true, disableDotRule: true,
...@@ -176,11 +225,12 @@ module.exports = (api, options) => { ...@@ -176,11 +225,12 @@ module.exports = (api, options) => {
server) server)
} }
})) }))
}
; ;
['SIGINT', 'SIGTERM'].forEach(signal => { ['SIGINT', 'SIGTERM'].forEach(signal => {
process.on(signal, () => { process.on(signal, () => {
server.close(() => { server[webpack.version[0] > 4 ? 'stopCallback' : 'close'](() => {
process.exit(0) process.exit(0)
}) })
}) })
...@@ -192,7 +242,7 @@ module.exports = (api, options) => { ...@@ -192,7 +242,7 @@ module.exports = (api, options) => {
process.stdin.on('data', data => { process.stdin.on('data', data => {
if (data.toString() === 'close') { if (data.toString() === 'close') {
console.log('got close signal!') console.log('got close signal!')
server.close(() => { server[webpack.version[0] > 4 ? 'stopCallback' : 'close'](() => {
process.exit(0) process.exit(0)
}) })
} }
...@@ -303,11 +353,15 @@ module.exports = (api, options) => { ...@@ -303,11 +353,15 @@ module.exports = (api, options) => {
server.showStatus = function () {} server.showStatus = function () {}
} }
if (webpack.version[0] > 4) {
server.start().catch(err => reject(err))
} else {
server.listen(port, host, err => { server.listen(port, host, err => {
if (err) { if (err) {
reject(err) reject(err)
} }
}) })
}
}) })
}) })
} }
......
...@@ -70,7 +70,11 @@ const v3 = { ...@@ -70,7 +70,11 @@ const v3 = {
webpackConfig.optimization = {} webpackConfig.optimization = {}
} }
// disable noEmitOnErrors // disable noEmitOnErrors
webpackConfig.optimization.noEmitOnErrors = false if (webpack.version[0] > 4) {
webpackConfig.optimization.emitOnErrors = true
} else {
webpackConfig.optimization.noEmitOnErrors = false
}
if (isAppService) { if (isAppService) {
webpackConfig.optimization.runtimeChunk = { webpackConfig.optimization.runtimeChunk = {
...@@ -134,7 +138,8 @@ const v3 = { ...@@ -134,7 +138,8 @@ const v3 = {
output: { output: {
filename: '[name].js', filename: '[name].js',
chunkFilename: '[id].js', chunkFilename: '[id].js',
globalObject: 'this' // webpack5 use strict
globalObject: webpack.version[0] > 4 ? `(new Function("return this")())` : 'this'
}, },
performance: { performance: {
hints: false hints: false
...@@ -158,7 +163,7 @@ const v3 = { ...@@ -158,7 +163,7 @@ const v3 = {
compiler: vueLoader.compiler, compiler: vueLoader.compiler,
before: [ before: [
beforeCode + require('../util').getAutomatorCode() + statCode + pushCode + uniCloudCode + beforeCode + require('../util').getAutomatorCode() + statCode + pushCode + uniCloudCode +
getGlobalUsingComponentsCode() getGlobalUsingComponentsCode()
] ]
} }
}] }]
......
const path = require('path') const path = require('path')
const webpack = require('webpack')
const { const {
sassLoaderVersion sassLoaderVersion
...@@ -23,11 +24,22 @@ module.exports = function chainWebpack (platformOptions, vueOptions, api) { ...@@ -23,11 +24,22 @@ module.exports = function chainWebpack (platformOptions, vueOptions, api) {
const urlLoader = require('@dcloudio/uni-cli-shared/lib/url-loader') const urlLoader = require('@dcloudio/uni-cli-shared/lib/url-loader')
const staticTypes = ['images', 'media', 'fonts'] const staticTypes = ['images', 'media', 'fonts']
staticTypes.forEach(staticType => { staticTypes.forEach(staticType => {
webpackConfig.module const newOptions = urlLoader.options()
.rule(staticType) if (webpack.version[0] > 4) {
.use('url-loader') if ('limit' in newOptions) {
.loader(urlLoader.loader) webpackConfig.module.rule(staticType).parser({
.tap(options => Object.assign(options, urlLoader.options())) 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三种类型,单独资源文件引用各自过滤 // 条件编译 vue 文件统一直接过滤html,js,css三种类型,单独资源文件引用各自过滤
......
const fs = require('fs') const fs = require('fs')
const path = require('path') const path = require('path')
const webpack = require('webpack') const webpack = require('webpack')
const RuleSet = require('webpack/lib/RuleSet')
const CopyWebpackPlugin = require('copy-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin')
const merge = require('webpack-merge') const merge = require('webpack-merge')
...@@ -39,6 +38,37 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt ...@@ -39,6 +38,37 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
return (rule, i) => { return (rule, i) => {
const clone = Object.assign({}, rule) const clone = Object.assign({}, rule)
delete clone.include 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, {}, '') const normalized = RuleSet.normalizeRule(clone, {}, '')
return ( return (
!rule.enforce && !rule.enforce &&
...@@ -47,6 +77,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt ...@@ -47,6 +77,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
) )
} }
} }
}
function updateJsLoader (rawRules, fakeFile, checkLoaderRegex, loader) { function updateJsLoader (rawRules, fakeFile, checkLoaderRegex, loader) {
const matchRule = rawRules.find(createMatcher(fakeFile)) const matchRule = rawRules.find(createMatcher(fakeFile))
...@@ -152,6 +183,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt ...@@ -152,6 +183,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
if (Array.isArray(uses)) { if (Array.isArray(uses)) {
if (uses.find(use => babelLoaderRe.test(use.loader))) { if (uses.find(use => babelLoaderRe.test(use.loader))) {
const index = uses.findIndex(use => cacheLoaderRe.test(use.loader)) const index = uses.findIndex(use => cacheLoaderRe.test(use.loader))
if (index >= 0) {
if (process.env.UNI_USING_CACHE) { if (process.env.UNI_USING_CACHE) {
Object.assign(uses[index].options, api.genCacheConfig( Object.assign(uses[index].options, api.genCacheConfig(
'babel-loader/' + process.env.UNI_PLATFORM, 'babel-loader/' + process.env.UNI_PLATFORM,
...@@ -163,6 +195,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt ...@@ -163,6 +195,7 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt
} }
} }
} }
}
// js preprocess // js preprocess
updateJsLoader(rawRules, 'foo.js', babelLoaderRe, { updateJsLoader(rawRules, 'foo.js', babelLoaderRe, {
......
const { const {
getPlatformCssnano getPlatformCssnano
} = require('@dcloudio/uni-cli-shared') } = require('@dcloudio/uni-cli-shared')
const webpack = require('webpack')
module.exports = function initCssnanoOptions (webpackConfig) { module.exports = function initCssnanoOptions (webpackConfig) {
const module = webpackConfig.module const module = webpackConfig.module
// TODO 临时 hack calc:false 看看 vue cli 后续是否开放 cssnano 的配置 // TODO 临时 hack calc:false 看看 vue cli 后续是否开放 cssnano 的配置
const cssnanoOptions = { const cssnanoOptions = {
sourceMap: false, sourceMap: false
plugins: [require('cssnano')({ }
const plugins = [require('cssnano')({
preset: ['default', getPlatformCssnano()] 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) module.rule('css').oneOf('vue-modules').use('cssnano').loader('postcss-loader').options(cssnanoOptions)
......
...@@ -160,9 +160,13 @@ module.exports = { ...@@ -160,9 +160,13 @@ module.exports = {
}, },
plugins, plugins,
optimization: { 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() watchOptions: require('../util').getWatchOptions()
} }
} }
......
...@@ -157,7 +157,11 @@ module.exports = { ...@@ -157,7 +157,11 @@ module.exports = {
webpackConfig.optimization = {} webpackConfig.optimization = {}
} }
// disable noEmitOnErrors // disable noEmitOnErrors
webpackConfig.optimization.noEmitOnErrors = false if (webpack.version[0] > 4) {
webpackConfig.optimization.emitOnErrors = true
} else {
webpackConfig.optimization.noEmitOnErrors = false
}
webpackConfig.optimization.runtimeChunk = { webpackConfig.optimization.runtimeChunk = {
name: 'common/runtime' name: 'common/runtime'
......
const fs = require('fs') const fs = require('fs')
const path = require('path') const path = require('path')
const webpack = require('webpack')
const isWin = /^win/.test(process.platform) const isWin = /^win/.test(process.platform)
...@@ -23,11 +24,11 @@ module.exports = function initOptions (options) { ...@@ -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(genTranspileDepRegex(path.resolve(process.env.UNI_INPUT_DIR, 'node_modules')))
options.transpileDependencies.push('@dcloudio/uni-' + process.env.UNI_PLATFORM) options.transpileDependencies.push('@dcloudio/uni-' + process.env.UNI_PLATFORM)
options.transpileDependencies.push('@dcloudio/uni-i18n') 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/uni-push')
options.transpileDependencies.push('@dcloudio/vue-cli-plugin-uni/packages/uni-app') 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-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') options.transpileDependencies.push('@dcloudio/vue-cli-plugin-uni/packages/uni-push')
if (process.env.UNI_PLATFORM !== 'mp-weixin') { // mp runtime if (process.env.UNI_PLATFORM !== 'mp-weixin') { // mp runtime
...@@ -59,8 +60,14 @@ module.exports = function initOptions (options) { ...@@ -59,8 +60,14 @@ module.exports = function initOptions (options) {
options.css.loaderOptions.sass = {} options.css.loaderOptions.sass = {}
} }
if (!options.css.loaderOptions.postcss.config) { if (webpack.version[0] > 4) {
options.css.loaderOptions.postcss.config = {} if (!options.css.loaderOptions.postcss.postcssOptions) {
options.css.loaderOptions.postcss.postcssOptions = {}
}
} else {
if (!options.css.loaderOptions.postcss.config) {
options.css.loaderOptions.postcss.config = {}
}
} }
// sass 全局变量 // sass 全局变量
...@@ -85,9 +92,10 @@ module.exports = function initOptions (options) { ...@@ -85,9 +92,10 @@ module.exports = function initOptions (options) {
} }
options.css.loaderOptions.sass.prependData = sassData options.css.loaderOptions.sass.prependData = sassData
const userPostcssConfigPath = path.resolve(process.env.UNI_INPUT_DIR, 'postcss.config.js') const userPostcssConfigPath = path.resolve(process.env.UNI_INPUT_DIR, 'postcss.config.js')
if (fs.existsSync(userPostcssConfigPath)) { const configPath = fs.existsSync(userPostcssConfigPath) ? userPostcssConfigPath : path.resolve(process.env.UNI_CLI_CONTEXT, 'postcss.config.js')
options.css.loaderOptions.postcss.config.path = userPostcssConfigPath if (webpack.version[0] > 4) {
options.css.loaderOptions.postcss.postcssOptions.config = configPath
} else { } else {
options.css.loaderOptions.postcss.config.path = path.resolve(process.env.UNI_CLI_CONTEXT, 'postcss.config.js') options.css.loaderOptions.postcss.config.path = configPath
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册