详解Webpack多环境代码打包的方法


Posted in Javascript onAugust 03, 2018

在实际开发中常遇到,代码在

在package.json文件的scripts中,会提供开发环境与生产环境两个命令。但是实际使用中会遇见 测试版与正式版代码相继发布的情况,这样反复更改服务器地址,偶尔忘记更改url会给工作带来很多不必要的麻烦(当然也会对你的工作能力产生质疑)。这样就需要在生产环境中配置测试版本打包命令与正式版本打包命令。

1、Package.json 文件中 增加命令行命令,并指定路径。

"scripts": {
  "dev": "node build/dev-server.js",
  "build": "node build/build.js",

//正式环境打包命令
  "fev": "node build/test.js"       //测试环境打包命令
 },

2、在build文件中添加相应文件

详解Webpack多环境代码打包的方法

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文件中增加环境变量配置

详解Webpack多环境代码打包的方法

test.env.js 增加环境变量

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文件中在增加环境变量判断

if(process.env.NODE_ENV == 'production'){
  defines.html_url = '正式环境URL';
}
if(process.env.NODE_ENV == 'development'){
defines.html_url = '开发环境URL';
} 
if(process.env.NODE_ENV == 'fev'){ 

defines.html_url = '测试环境URL'; 
}

5、如果公共资源路径,在不同环境中需要更改。在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 = {

 //测试使用
 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]')
    }
   }
  ]
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
判断js中各种数据的类型方法之typeof与0bject.prototype.toString讲解
Nov 07 Javascript
用js代码改变单选框选中状态的简单实例
Dec 18 Javascript
判断浏览器的内核及版本号方法汇总
Jan 05 Javascript
jQuery实现的fixedMenu下拉菜单效果代码
Aug 24 Javascript
JavaScript中实现Map的示例代码
Sep 09 Javascript
深入解析桶排序算法及Node.js上JavaScript的代码实现
Jul 06 Javascript
JS中数组重排序方法
Nov 11 Javascript
如何理解Vue的.sync修饰符的使用
Aug 17 Javascript
详细介绍RxJS在Angular中的应用
Sep 23 Javascript
基于React Native 0.52实现轮播图效果
Aug 25 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
Jul 02 Javascript
Vue包大小优化的实现(从1.72M到94K)
Feb 18 Vue.js
浅析vue-router jquery和params传参(接收参数)$router $route的区别
Aug 03 #jQuery
浅析Vue 和微信小程序的区别、比较
Aug 03 #Javascript
Vue 项目分环境打包的方法示例
Aug 03 #Javascript
如何在vue里添加好看的lottie动画
Aug 02 #Javascript
原生js实现form表单序列化的方法
Aug 02 #Javascript
详解基于Vue2.0实现的移动端弹窗(Alert, Confirm, Toast)组件
Aug 02 #Javascript
详解vue指令与$nextTick 操作DOM的不同之处
Aug 02 #Javascript
You might like
php根据用户语言跳转相应网页
2015/11/04 PHP
smarty学习笔记之常见代码段用法总结
2016/03/19 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
Javascript 生成指定范围数值随机数
2009/01/09 Javascript
javascript权威指南 学习笔记之javascript数据类型
2011/09/24 Javascript
JS中Date日期函数中的参数使用介绍
2014/01/02 Javascript
ECMAScript 5中的属性描述符详解
2015/03/02 Javascript
JavaScript实现带标题的图片轮播特效
2015/05/20 Javascript
jQuery 中的 DOM 操作
2016/04/26 Javascript
浅谈jquery中使用canvas的问题
2016/10/10 Javascript
Vue实现选择城市功能
2017/05/27 Javascript
详解小程序开发经验:多页面数据同步
2019/05/18 Javascript
vue router总结 $router和$route及router与 router与route区别
2019/07/05 Javascript
[04:50]DOTA2亚洲邀请赛小组赛第四日 TOP10精彩集锦
2015/02/02 DOTA
[03:17]2016完美“圣”典风云人物:冷冷专访
2016/12/08 DOTA
[57:24]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python字符串详细介绍
2015/05/09 Python
Python中的字符串替换操作示例
2016/06/27 Python
基于Django模板中的数字自增(详解)
2017/09/05 Python
python shell根据ip获取主机名代码示例
2017/11/25 Python
Django中redis的使用方法(包括安装、配置、启动)
2018/02/21 Python
Python 生成 -1~1 之间的随机数矩阵方法
2018/08/04 Python
Tesserocr库的正确安装方式
2018/10/19 Python
解决pandas.DataFrame.fillna 填充Nan失败的问题
2018/11/06 Python
python实现批量视频分帧、保存视频帧
2019/05/31 Python
Django中信号signals的简单使用方法
2019/07/04 Python
python获取指定日期范围内的每一天,每个月,每季度的方法
2019/08/08 Python
基于Django框架的权限组件rbac实例讲解
2019/08/31 Python
Python有参函数使用代码实例
2020/01/06 Python
Python continue语句实例用法
2020/02/06 Python
MATCHESFASHION澳大利亚/亚太地区:英国时尚奢侈品电商
2020/01/14 全球购物
意大利买卖二手奢侈品网站:LAMPOO
2020/06/03 全球购物
小学少先队活动方案
2014/02/18 职场文书
纪念九一八事变演讲稿:青少年应树立远大理想
2014/09/14 职场文书
检讨书格式
2015/01/23 职场文书
毕业论文答辩开场白
2015/05/27 职场文书