在項目開發的時候,我們通常會將程序分為開發環境和生產環境(或者叫線上環境),開發環境通常指的是我們正在開發的這個階段所需要的一些環境配置,也就是方便我們開發人員調試開發的一種環境;生產環境通常指的是我們將程序開發完成經過測試之后無明顯異常准備發布上線的環境,也可以理解為用戶可以正常使用的就是生產環境;
當然開發環境和生產環境在配置方面的需求是不一樣的,但是有共同點:
開發環境的需求:
模塊熱更新 (本地開啟服務,實時更新)
sourceMap (方便打包調試)
接口代理 (配置proxyTable解決開發環境中的跨域問題)
代碼規范檢查 (代碼規范檢查工具)
生產環境的需求:
提取公共代碼
壓縮混淆(壓縮混淆代碼,清除代碼空格,注釋等信息使其變得難以閱讀)
文件壓縮/base64編碼(壓縮代碼,減少線上環境文件包的大小)
去除無用的代碼
開發環境和生產環境的共同需求:
同樣的入口
同樣的代碼處理(loader處理)
同樣的解析配置
在我們搭建好Vue-cli腳手架之后,我們的build文件夾會分別自動的生成webpack.base.conf.js、webpack.dev.conf.js、webpack.prod.conf.js三個webpack配置文件;
webpack.base.conf.js:webpack的開發環境和生產環境的共有配置(開發環境和生產環境都是需要執行的配置)
webpack.dev.conf.js:webpack的開發環境的特有配置(只在開發環境中執行,生產環境中不執行)
webpack.prod.conf.js:webpack的生產環境的特有配置(只在生產環境中執行,開發環境中不執行)
我們為什么要區分開發環境和生產環境呢?
因為一個項目的開發過程中肯定不會是一個版本開發完之后就立馬上線,開發是必需,上線是目的;在開發的過程中會有各種各樣的問題,比如開發環境中跨域、開發環境和生產環境因環境不同而產生的未知奇葩錯誤等等都是會時常發生的,我們區分環境的目的就是為了讓開發人員在開發的過程中可以方便調試,保持高效的開發;讓程序在生產環境中正常有效的運行;
webpack.base.conf.js配置
const path = require('path'); //清除build/dist文件夾文件 const CleanWebpackPlugin = require('clean-webpack-plugin'); //生成創建Html入口文件 const HtmlWebpackPlugin = require('html-webpack-plugin'); //將css提取到單獨的文件中 const MiniCssExtract = require('mini-css-extract-plugin'); //css壓縮 const OptimizeCss = require('optimize-css-assets-webpack-plugin'); //壓縮js文件 const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); //引入webpack const webpack = require('webpack'); module.exports = { //webpack 入口文件 entry: './src/index.js', //webpack 輸出文件配置 output: { //輸出文件路徑 path: path.resolve(__dirname, 'dist'), //輸出文件名 filename: 'k-editor.[hash:8].js', }, //配置插件 plugins: [ //使用插件清除dist文件夾中的文件 new CleanWebpackPlugin({ path: './dist' }), //使用插件生成Html入口文件 new HtmlWebpackPlugin({ //模板文件路徑 template: "./src/index.html", //模板文件名 filename: "index.html", minify: { removeAttributeQuotes: true, //刪除雙引號, collapseWhitespace: true, //壓縮成一行, }, hash: true }), //提取css到style.css中 new MiniCssExtract({ filename: 'style.css' }), ], resolve: { // modules: [path.resolve('node_modules')],//只在當前目錄下查找 alias: { //別名 'bootstrap': 'bootstrap/dist/css/bootstrap.css', }, // mainFields: ['style', 'main'],//優先尋找style, // mainFiles: [],//入口文件的名字,默認index.js // extensions: ['js', 'css', 'json', 'vue']//擴展名順序 }, //loader加載器模塊配置 module: { rules: [ { //正則表達式匹配.css為后綴的文件 test: /\.css$/, //使用loader use: [ MiniCssExtract.loader, 'css-loader', { loader: "postcss-loader" }, ] //正則表達式匹配.less為后綴的文件 //使用lodaer來處理 }, { test: /\.less$/, use: [ MiniCssExtract.loader, 'css-loader', { loader: "postcss-loader" }, 'less-loader' ] }, /* { test: /\.js$/, //不包括node_modules exclude: /node_modules/, use: [{ loader: "eslint-loader", options: { enforce: 'pre' //強制更改順序,pre 前 post 后 } }], },*/ { test: /\.js$/, //普通的loader //不包括node_modules exclude: /node_modules/, use: [{ loader: "babel-loader" }] }, { test: /\.html$/, use: ['html-withimg-loader'] }, { test: /\.(gif|png|jpg)$/, use: [{ loader: "url-loader", options: { //圖片小於10kb就是圖片地址,大於正常打包成base64格式編碼 limit: 10000, //輸出路徑 outputPath: 'img/' } }] } ] }, };
webpack.dev.conf.js:
//引入webpack-merge插件進行合並 const {merge} = require('webpack-merge'); //引入webpack.base.conf.js文件 const base = require('./webpack.base.conf'); //引入webpack const webpack = require('webpack'); //進行合並,將webpack.base.conf.js中的配置合並到這 module.exports = merge(base, { //模塊參數 mode: 'development', devServer: { contentBase: './dist', //端口號 port: '8383', inline: true, historyApiFallback: true,//在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html hot: true//允許熱加載 }, //啟用source-map方便調試 devtool: 'source-map', plugins: [ //定義全局變量 new webpack.DefinePlugin({ //這里必須要解析成字符串進行判斷,不然將會被識別為一個變量 DEV: JSON.stringify('dev') }) ] });
webpack.prod.conf.js:
const {merge} = require('webpack-merge'); const base = require('./webpack.base'); const path = require('path'); const OptimizeCss = require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const webpack = require('webpack'); module.exports = merge(base, { mode: 'production', optimization: { minimizer: [ //壓縮CSS代碼 new OptimizeCss(), //壓縮js代碼 new UglifyJsPlugin({ //啟用文件緩存 cache: true, //使用多線程並行運行提高構建速度 parallel: true, //使用 SourceMaps 將錯誤信息的位置映射到模塊 sourceMap: true }) ] }, plugins:[ //使用插件定義全局變量DEV new webpack.DefinePlugin({ DEV:JSON.stringify('production') }) ] });
最后在配置一下package.json文件就可以了:
"scripts": { "test": "npm run test", "dev": "webpack-dev-server --config webpack.dev.js", "build": "webpack --config webpack.prod.js" },
如何區分開發環境和生產環境呢?
在node中,我們有一個對象process對象,它里面包括的一些信息,env和它的一些屬性,當然NODE_ENV是我們自己加上去的自定義屬性,用來區分環境變量,也就是通過這個變量來進行區別是開發環境還是生產環境;但是有個問題,不同電腦上設置的方式是不一樣的,所以cross-env就來了,它可以跨平台設置環境和使用環境變量。
npm install cross-env
我們在webpack.base.conf.js文件中修改代碼:
const NODE_ENV=process.env.NODE_ENV;
console.log(NODE_ENV);
然后我們修改package.json文件:
//--config是可以設置我們執行哪個webpack文件,默認是執行webpack.config.js,但是我們現在修改文件名了,所以我們要設置一下 "build": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js", "dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.dev.js"
就這樣,我們就實現了利用webpack來區分開發環境和生產環境,當我們用npm run dev運行的時候就是開發環境,當我們運行npm run build的時候就是構建生產環境打包;
對了,最后再多說一句,從今天開始,本文作者的個人微信公眾號正式開通(公眾號已接入第七代微軟小冰AI機器人),后期文章微信公眾號將同步更新,如果覺得文章對你有幫助,可以掃碼關注一下: