vue2 webpack3 升级 webpack5 全过程,内附详细配置文件
由于 webpack5 需要 node 版本>=10.13.0,请先将 node版本 升级, npm版本 用node自带的就可以了。官方最新的node版本好像不兼容下面的webpack5配置,建议升级成 LTS版本 ,这里我升级的是v14.18.1的LTS版本,可以完美兼容。配置代码我怕各种不兼容你们拿去不能用,索性全部贴出来,用到什么参考下我的版本,这些版本间的兼容性一言难尽,不要问我为什
由于 webpack5 需要 node 版本>= 10.13.0,请先将 node版本 升级, npm版本 用node自带的就可以了。
官方最新的node版本好像不兼容下面的webpack5配置,建议升级成 LTS版本 ,这里我升级的是v14.18.1的LTS版本,可以完美兼容。
配置代码我怕各种不兼容你们拿去不能用,索性全部贴出来,用到什么参考下我的版本,这些版本间的兼容性一言难尽,不要问我为什么不用最新的,不是最新的就是最好(它不兼容啊),但是不够新一定不行。
webpack5 相关的配置就 babel7 和 名字与webpack相关的依赖
主要和webpack3的配置区别就是几个依赖弃用和新的依赖支持
ExtractTextPlugin, OptimizeCSSPlugin, UglifyJsPlugin => MiniCssExtractPlugin, CssMinimizerPlugin ,TerserWebpackPlugin
merge => { merge }
VueLoaderPlugin 的添加
.postcssrc.js => postcss.config.js
这些后面配置文件里都会贴,找不同改下就好了
package.json
{
"name": "",
"version": "",
"description": "",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack server --inline --progress --config build/webpack.dev.conf.js",
"build": "cross-env NODE_ENV=production webpack --config build/webpack.prod.conf.js",
"start": "npm run dev",
"check": "cross-env npm-check"
},
"dependencies": {
"@babel/polyfill": "^7.0.0",
"@babel/runtime": "^7.15.3",
"@babel/runtime-corejs2": "^7.15.3",
"axios": "^0.18.0",
"diff": "^5.0.0",
"echarts": "^5.2.1",
"element-ui": "^2.15.6",
"jquery": "^3.5.1",
"js-cookie": "^2.2.1",
"lodash": "^4.17.15",
"npm-check": "^5.9.2",
"qs": "^6.9.4",
"sortablejs": "^1.13.0",
"vue": "^2.6.10",
"vue-i18n": "^8.18.2",
"vue-meta": "^1.5.8",
"vue-router": "^3.0.1",
"vue-virtual-scroll-list": "^2.3.2",
"vuex": "^3.0.1",
"wangeditor": "^4.6.16"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"acorn": "^8.5.0",
"autoprefixer": "^7.1.2",
"babel-eslint": "^9.0.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^8.0.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"chalk": "^2.0.1",
"compression-webpack-plugin": "^9.0.0",
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^7.0.2",
"css-loader": "^5.2.7",
"css-minimizer-webpack-plugin": "^3.1.1",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^4.0.0",
"file-loader": "^6.2.0",
"filemanager-webpack-plugin": "^2.0.5",
"friendly-errors-webpack-plugin": "^1.7.0",
"html-webpack-plugin": "^5.4.0",
"increase-memory-limit": "^1.0.7",
"mini-css-extract-plugin": "^2.4.3",
"node-notifier": "^5.1.2",
"ora": "^1.2.0",
"portfinder": "^1.0.28",
"postcss": "^8.2.15",
"postcss-import": "^14.0.2",
"postcss-loader": "^6.2.0",
"postcss-url": "^10.1.3",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"style-loader": "^3.3.1",
"stylus": "^0.54.8",
"stylus-loader": "^3.0.2",
"svg-sprite-loader": "^5.2.1",
"url-loader": "^4.1.1",
"vue-loader": "^15.8.0",
"vue-loader-plugin": "^1.3.0",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.37.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.0",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3",
"webpackbar": "^5.0.0-3"
},
"engines": {
"node": ">= 10.13.0",
"npm": ">= 6.4.1"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
build
build.js
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
packZip.js
const pack = require('../package.json')
const path = require('path')
const FileManagerPlugin = require('filemanager-webpack-plugin')
const multiConfig = require('../config/multi.conf')
const argvs = process.argv.slice(2)
function getParams (key) {
let item = argvs.find(item => item.split('=')[0] === key)
return item ? item.split('=') : []
}
let datetime = Date.now()
let plugins = []
let zipPros = getParams('zip')
if (zipPros.length) {
plugins.push(new FileManagerPlugin({
onEnd: {
archive: [{
source: path.resolve(__dirname, `${argvs[0]}`),
destination: path.resolve(__dirname, zipPros[1] ? `${argvs[0]}.zip` : `${argvs[0]}.zip`)
}]
}
}))
}
module.exports = plugins
utils.js
'use strict'
const path = require('path')
const config = require('../config')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders(loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return [
{
loader: MiniCssExtractPlugin.loader,
}
].concat(loaders)
} else {
return [
{
loader: 'vue-style-loader'
}
].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
webpack.base.conf.js
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const webpack = require('webpack')
const { VueLoaderPlugin } = require('vue-loader');
const multiConfig = require('../config/multi.conf')
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
module.exports = {
context: path.resolve(__dirname, '../'),
entry: multiConfig.process.entry,
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@comm': resolve(`src/common`),
'@url': resolve('src/proxyUrl'),
'@static': resolve('src'),
'@': multiConfig.process.alias,
...multiConfig.moduleAlias
},
fallback: {
fs: false
}
},
module: {
rules: [
// ...(config.dev.useEslint ? [createLintingRule()] : []), //eslint校验
{
test: /\.vue$/,
use: ['vue-loader'],
},
{
test: /\.js$/,
use: ['babel-loader?cacheDirectory=true'], //babel-loader 开启缓存
include: [resolve('src'), resolve('test')],
exclude: resolve('node_modules'),
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
],
exclude: [resolve('../node_modules')],
},
{
test: /\.styl(us)?$/,
use: [
'style-loader',
'css-loader',
'stylus-loader',
],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]'),
esModule: false,
}
},
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/common/svgIcons')],
options: {
symbolId: 'icon-[name]'
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
},
]
},
node: {
global: false
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}),
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/lib\/chart\/(.)*/,
contextRegExp: /echarts$/,
}), //打包忽略echarts
new VueLoaderPlugin(),
]
}
webpack.dev.conf.js
'use strict'
const os = require('os')
const fs = require('fs')
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const pack = require('../package.json')
const { merge } = require('webpack-merge')
const chalk = require('chalk')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const multiConfig = require('../config/multi.conf')
const WebpackBar = require('webpackbar')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
function getIPAdress() {
var interfaces = os.networkInterfaces()
for (var devName in interfaces) {
var iface = interfaces[devName]
for (var i = 0; i < iface.length; i++) {
var alias = iface[i]
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
return alias.address
}
}
}
}
function isExists(path) {
try {
fs.statSync(path)
return true
} catch (e) {
return false
}
}
function porxyStatic() {
return {
'/static': {
target: `http://${config.dev.host}:${config.dev.port}`,
bypass: function (req, res, proxyOptions) {
if (req.path.indexOf(`/${config.dev.assetsSubDirectory}/`) === 0) {
let publics = multiConfig.process.publics
for (let len = publics.length - 1; len >= 0; len--) {
let pubPath = req.path.replace(`/${config.dev.assetsSubDirectory}/`, `/${config.dev.assetsSubDirectory}/${publics[len]}/`)
if (isExists(path.resolve(__dirname, `../${pubPath}`))) {
return pubPath
}
}
return req.path
}
}
}
}
}
const devWebpackConfig = merge(baseWebpackConfig, {
mode: 'development',
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: Object.assign(porxyStatic(), config.dev.proxyTable, multiConfig.process.proxyTable),
quiet: true, // necessary for FriendlyErrorsPlugin
// useLocalIp: true,//用本地ip
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
favicon: path.resolve('./src/common/images/favicon.ico'),
inject: true,
chunkSortMode: 'auto'
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
globOptions: {
dot: true,
gitignore: true,
ignore: ['.*'],
}
}
]),
new WebpackBar()
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
let host = ['localhost', '127.0.0.1', '0.0.0.0'].includes(devWebpackConfig.devServer.host) ? 'localhost' : devWebpackConfig.devServer.host
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [chalk`{bold.rgb(255,255,0) [${pack.name} => ${multiConfig.process.name}]} App running at:\n - Local: {bold.cyan http://${host}:${port}${config.dev.assetsPublicPath}}\n - Network: {bold.cyan http://${getIPAdress()}:${port}${config.dev.assetsPublicPath}}`]
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
webpack.prod.conf.js
'use strict'
const fs = require('fs')
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const { merge } = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const multiConfig = require('../config/multi.conf')
const TerserWebpackPlugin = require('terser-webpack-plugin');
const env = require('../config/prod.env')
function isDirectory(path) {
try {
let stat = fs.statSync(path)
return stat.isDirectory()
} catch (e) {
return false
}
}
const webpackConfig = merge(baseWebpackConfig, {
mode: "production",
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js'),
clean: true
},
optimization: {
minimize: true,
minimizer: [
new TerserWebpackPlugin({
parallel: true,
extractComments: false,
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
},
format: {
comments: false
}
}
}),
new CssMinimizerPlugin(),
],
runtimeChunk: { name: 'runtime' },
concatenateModules: true,
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all',
priority: -10
},
'async-vendors': {
test: /[\\/]node_modules[\\/]/,
minChunks: 2,
chunks: 'async',
name: 'async-vendors'
}
},
},
moduleIds: 'deterministic'
},
plugins: [
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
chunkFilename: utils.assetsPath('css/[name].[contenthash].css')
}),
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
favicon: path.resolve('./src/common/images/favicon.ico'),
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'auto'
}),
// copy custom static assets
new CopyWebpackPlugin(multiConfig.process.publics.filter(name => isDirectory(path.resolve(__dirname, `../static/${name}`))).map(name => {
return {
from: path.resolve(__dirname, `../static/${name}`),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
})),
// pack zip
...require('./packZip')
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
config
dev.env.js
'use strict'
const { merge } = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
index.js
'use strict'
const path = require('path')
const multiConfig = require('./multi.conf')
module.exports = {
dev: {
// Paths
assetsSubDirectory: multiConfig.process.assetsSubDirectory,
assetsPublicPath: multiConfig.process.assetsPublicPath,
proxyTable: multiConfig.process.proxyTable,
// Various Dev Server settings
host: multiConfig.process.host, // can be overwritten by process.env.HOST
port: multiConfig.process.port, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: true, //自动打开浏览器
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: true,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
devtool: 'cheap-module-source-map',
cacheBusting: true,
cssSourceMap: true,
},
build: {
// Template for index.html
index: multiConfig.process.index,
// Paths
assetsRoot: multiConfig.process.assetsRoot,
assetsSubDirectory: multiConfig.process.assetsSubDirectory,
assetsPublicPath: multiConfig.process.assetsBuildPublicPath + '/',
/**
* Source Maps
*/
productionSourceMap: true,
devtool: 'source-map',
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
bundleAnalyzerReport: process.env.npm_config_report
}
}
multi.conf.js
const path = require('path')
const pack = require('../package.json')
const argvs = process.argv.slice(2)
const urlConfig = require('../src/proxyUrl/proxyUrl')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
function getParams (key) {
let item = argvs.find(item => item.split('=')[0] === key)
return item ? item.split('=') : []
}
function getModuleAlias () {
let alias = {}
importModules.forEach(({ name }) => {
alias[`@${name}`] = resolve(`src/${name}`)
})
return alias
}
class MultiModule {
constructor (name, opts) {
let datetime = Date.now()
Object.assign(this, {
name,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
port: 8080,
host: 'localhost',
proxyTable: null,
entry: {
app: ['@babel/polyfill', `./src/${name}/main.js`]
},
alias: resolve(`src/${name}`),
index: path.resolve(__dirname, `${argvs[0]}/template/index.html`),
// favicon: path.resolve(__dirname, `E:/build/${name}/favicon.ico`),
assetsRoot: path.resolve(__dirname, `${argvs[0]}/template`),
pubdate: `${name}_v${pack.version}_${datetime}`,
publics: [name].concat(opts.statics || []),
deployConfig: null
}, opts)
}
}
function getModuleProcess (name) {
let mItem = importModules.find(item => item.name === name)
return mItem || importModules[0]
}
function proxyHandle (proxyReq, req, res, options) {
let origin = `${options.target.protocol}//${options.target.hostname}`
proxyReq.setHeader('origin', origin)
proxyReq.setHeader('referer', origin)
}
function onProxyReq (proxyReq, req, res, options) {
proxyHandle(proxyReq, req, res, options)
}
function onProxyReqWs (proxyReq, req, socket, options, head) {
proxyHandle(proxyReq, req, socket, options)
}
function getProxyConfig (targetOpt, options) {
let target = targetOpt.isLocal ? targetOpt.target.substring(0, targetOpt.target.length - 1) : targetOpt.target + targetOpt.name
return Object.assign({
target,
// secure: false,
changeOrigin: true,
secure: false,
// ws: false,
// cookieDomainRewrite: { '*': '' },
// cookiePathRewrite: { '*': '/' },
pathRewrite: {'^/API': target},
// onProxyReq,
// onProxyReqWs
}, options)
}
const PROXY_DOMAIN_DEFAULT = urlConfig.url
const IS_LOCAL = urlConfig.isLocal
// 多模块独立配置
var importModules = [
new MultiModule('*****', {
port: 7007,
statics: ['****'],
assetsBuildPublicPath: getProxyConfig({target: PROXY_DOMAIN_DEFAULT, name: '****', isLocal: IS_LOCAL}).target,
proxyTable: {
'/API': getProxyConfig({target: PROXY_DOMAIN_DEFAULT, name: '', isLocal: IS_LOCAL})
}
}),
]
var lifecycleEvents = String(process.env.npm_lifecycle_event).split(':')
var moduleName = getParams('name')[1] || lifecycleEvents[1]
const multiConfig = {
modules: importModules,
moduleAlias: getModuleAlias(),
process: getModuleProcess(moduleName)
}
module.exports = multiConfig
prod.env.js
'use strict'
module.exports = {
NODE_ENV: '"production"'
}
proxyUrl
mode.js
let mode = {
uat: 'uat',
dev: 'dev',
online: 'online',
}
module.exports = mode.dev
proxyUrl.js
const mode = require('./mode')
const urlList = {
uat: '',
dev: '',
online: '',
}
module.exports = {
url: urlList[mode],
isLocal: !urlList[mode].includes('*****')
}
postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
.babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"browsers": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
}
]
],
"plugins": [
"transform-vue-jsx",
[
"@babel/plugin-transform-runtime",
{
"corejs": 2
}
],
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-json-strings",
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions",
[
"module-resolver",
{
"root": [
"element-ui"
],
"alias": {
"element-ui/src": "element-ui/lib"
}
}
]
]
}
更多推荐
所有评论(0)