詳解Webpack多環(huán)境代碼打包的方法
在實(shí)際開發(fā)中常遇到,代碼在
在package.json文件的scripts中,會(huì)提供開發(fā)環(huán)境與生產(chǎn)環(huán)境兩個(gè)命令。但是實(shí)際使用中會(huì)遇見 測(cè)試版與正式版代碼相繼發(fā)布的情況,這樣反復(fù)更改服務(wù)器地址,偶爾忘記更改url會(huì)給工作帶來(lái)很多不必要的麻煩(當(dāng)然也會(huì)對(duì)你的工作能力產(chǎn)生質(zhì)疑)。這樣就需要在生產(chǎn)環(huán)境中配置測(cè)試版本打包命令與正式版本打包命令。
1、Package.json 文件中 增加命令行命令,并指定路徑。
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js", //正式環(huán)境打包命令
"fev": "node build/test.js" //測(cè)試環(huán)境打包命令
},
2、在build文件中添加相應(yīng)文件

test.js
// https://github.com/shelljs/shelljs
require('./check-versions')()
process.env.NODE_ENV = 'fev'
var ora = require('ora')
var path = require('path')
var chalk = require('chalk')
var shell = require('shelljs')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.test.conf')
var spinner = ora('building for fev...')
spinner.start()
var assetsPath = path.join(config.fev.assetsRoot, config.fev.assetsSubDirectory)
shell.rm('-rf', assetsPath)
shell.mkdir('-p', assetsPath)
shell.config.silent = true
shell.cp('-R', 'static/*', assetsPath)
shell.config.silent = false
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
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'
))
})
webpack.test.conf.js
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var env = config.fev.env
var webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.fev.productionSourceMap,
extract: true
})
},
devtool: config.fev.productionSourceMap ? '#source-map' : false,
output: {
path: config.fev.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_console: true
},
sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.fev.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
})
]
})
if (config.fev.productionGzip) {
var CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.fev.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.fev.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
3、在config文件中增加環(huán)境變量配置

test.env.js 增加環(huán)境變量
module.exports = {
NODE_ENV: '"fev"'
}
index.js
// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')
module.exports = {
build: {
env: require('./prod.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
// assetsPublicPath: './',
assetsPublicPath: '', //公共資源路徑
productionSourceMap: false,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
fev: {
env: require('./test.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './', //公共資源路徑
productionSourceMap: false,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
test: {
env: require('./test.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
productionSourceMap: false,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
dev: {
env: require('./dev.env'),
port: 8081,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
// '/api':{
// target:'http://jsonplaceholder.typicode.com',
// changeOrigin:true,
// pathRewrite:{
// '/api':''
// }
// }
},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
}
4、在main.js文件中在增加環(huán)境變量判斷
if(process.env.NODE_ENV == 'production'){
defines.html_url = '正式環(huán)境URL';
}
if(process.env.NODE_ENV == 'development'){
defines.html_url = '開發(fā)環(huán)境URL';
}
if(process.env.NODE_ENV == 'fev'){
defines.html_url = '測(cè)試環(huán)境URL';
}
5、如果公共資源路徑,在不同環(huán)境中需要更改。在webpack.base.conf.js 中配置打包文件輸出的公共路徑。
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
//增加文件路徑判斷
var webpack_public_path = '';
if(process.env.NODE_ENV === 'production'){
webpack_public_path = config.build.assetsPublicPath;
}else if(process.env.NODE_ENV === 'fev'){
webpack_public_path = config.fev.assetsPublicPath;
}else if(process.env.NODE_ENV === 'dev'){
webpack_public_path = config.dev.assetsPublicPath;
}
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
//測(cè)試使用
entry: {
app: ["promise-polyfill", "./src/main.js"]
},
// entry: {
// app: './src/main.js'
// },
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: webpack_public_path
// publicPath: process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'fev' ? config.build.assetsPublicPath
// : config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
modules: [
resolve('src'),
resolve('node_modules'),
],
alias: {
'vue$': 'vue/dist/vue.common.js',
'src': resolve('src'),
'assets': resolve('src/assets'),
'components': resolve('src/components'),
'vendor': path.resolve(__dirname, '../src/api'),
// 'vendor': path.resolve(__dirname, '../src/vendor'),
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript?ESLint插件保姆級(jí)使用教程
ESLint最初是由Nicholas C. Zakas 于2013年6月創(chuàng)建的開源項(xiàng)目。它的目標(biāo)是提供一個(gè)插件化的javascript代碼檢測(cè)工具2022-08-08
對(duì)JavaScript的eval()中使用函數(shù)的進(jìn)一步討論
《JavaScript語(yǔ)言精髓與編程實(shí)踐》的讀者I22141提出了一問(wèn)題:為什么下面這段代碼在JScript 和SpiderMonkey中表現(xiàn)不一樣:2008-07-07
js+數(shù)組實(shí)現(xiàn)網(wǎng)頁(yè)上顯示時(shí)間/星期幾的實(shí)用方法
在網(wǎng)頁(yè)上顯示時(shí)間(年月日/時(shí)分秒),很多新手朋友都想實(shí)現(xiàn)這樣的功能,本文整理了一些實(shí)用技巧,殺出來(lái)與大家分享,感興趣的朋友可以了解下2013-01-01
低代碼從0到1創(chuàng)建小程序項(xiàng)目詳解流程
低代碼作為開發(fā)工具類的產(chǎn)品,需要有從0到1體系化的教程才可以,而且還得有教師進(jìn)行輔助。否則,學(xué)習(xí)低代碼是有難度的,入門很難。因?yàn)榇蠹伊?xí)慣了用代碼編程,一下子過(guò)度到可視化編程,有一個(gè)思路上的轉(zhuǎn)變2022-08-08
JavaScript日期時(shí)間與時(shí)間戳的轉(zhuǎn)換函數(shù)分享
這篇文章主要介紹了JavaScript日期時(shí)間與時(shí)間戳的轉(zhuǎn)換函數(shù)分享,本文給出兩個(gè)函數(shù)實(shí)現(xiàn)日期時(shí)間和時(shí)間戳間的轉(zhuǎn)換,需要的朋友可以參考下2015-01-01

