webpack配置打包
一、webpack基本安裝
1、建立webpack專案目錄如webpackDemo,並進入webpackDemo;
2、 在node已經安裝的前提下,開啟命令列控制器,輸入如下命令:
npm init -y npm install webpack webpack-cli --save-dev //安裝webpack webpack-cli
(MacOS: sudo npm install webpack webpack-cli -g,sudo npm isntall webpack webpack-cli --save-dev)
命令執行結束後,會生成package.json、package_lock.json、node_modules檔案。然後手動建立src目錄與package.json平級,src目錄下有index.html ,index.js 。
注:npm使用的是淘寶映象,使用命令 npm install --registry=https://registry.npm.taobao.org express (臨時使用);
(MacOS 如果上面命令不生效,可以使用此命令: npm config set registry https://registry.npm.taobao.org).
二、webpack概念
1、 webpack有四個核心概念:entry(入口) 、output(輸出)、loader、plugin(外掛)。
entry(入口)
告訴webpack構建內部依賴圖開始的模組;可以指定單入口起點檔案或多入口起點檔案。
module.exports = { entry:"./src/index.js" }
output(輸出)
告訴webpack輸出建立的bundles,以及如何命名檔案。指定編譯後的輸出檔案路徑。
const OUTPUT_FILE_NAME = "dist" module.exports = { entry:"./src/index.js", output: { filename: "[name].[contenthash:10].js", //輸出檔名稱, hash解決快取問題 path: path.resolve(__dirname,'dist') //輸出檔案路徑 } }
loader
loader可以讓webpack可以處理非JavaScript檔案,webpack本身只能處理JavaScript。
webpack配置loader有兩個目標:
a). test屬性,用於被對應的loader進行轉換的某個和某些檔案;
b). use屬性,表示進行轉換時,應該使用哪個loader;
module.exports = { output: { filename: "[name].[contenthash:10].js", //輸出檔名稱, hash解決快取問題 path: path.resolve(__dirname, OUTPUT_FILE_NAME) //輸出檔案路徑 }, module: { rules: [{ //整理html的img資源, test: /\.html$/, use: ["html-loader"] }, { //處理css資源 test: /\.css$/, use: ["css-loader", "style-loader"] }, { //處理JS資源 test: /\.jsx?$/, use: ['file-loader'] }] } }
外掛plugins
loader用於轉換某些型別,外掛用於執行更廣泛的任務。若使用一個外掛,只需require(),然後新增到陣列中。
module.exports = { ..., plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", hash: true }), new MiniCssExtarctPlugin({ filename: 'css/[name].[contenthash:10].css', path: path.resolve(__dirname,'dist') }) ] }
附全部程式碼:
package.json
{ "name": "webpack_demo", "version": "1.0.0", "description": "", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "watch": "webpack --watch", "start": "webpack --config webpack.config.js", "build": "webpack --config webpack.config.pro.js" }, "keywords": [], "author": "", "license": "ISC" }
webpack.config.js
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtarctPlugin = require("mini-css-extract-plugin"); //將css從js中提取出來 const OUTPUT_FILE_NAME = "dist"; module.exports = { entry: "./src/index.js", output: { filename: "[name].[contenthash:10].js", //輸出檔名稱,hash解決快取問題,具體可見下面的解釋 path: path.resolve(__dirname, OUTPUT_FILE_NAME) //輸出檔案路徑 }, mode: "development", //開發環境,生產環境使用"production" module: { rules: [{ //整理html的img資源, test: /\.html$/, use: ["html-loader"] }, { //處理css資源 test: /\.css$/, use: [ //將css檔案整合到JS檔案中 "css-loader", //建立style標籤,將樣式放入 "style-loader", // css相容性處理:postcss-->postcss-loader postcss-preset-env ] }, { //處理JS資源 test: /\.js$/, exclude: /node_modules/, //處理除了nodde_modules裡的js檔案 loader: 'babel-loader' //用babel-loader處理 }, { //處理圖片資源 test: /\.(png|svg|jpg|gif)$/, use: ['file-loader'] }, { // exclude: /\.(css|js|html)$/, //排除正則內的資源 test: /\.(png|svg|jpg|gif)$/, // 這裡是匹配條件,每個選項都接收一個正則表示式或字串 // test 和 include 具有相同的作用,都是必須匹配選項 // exclude 是必不匹配選項(優先於 test 和 include) // 最佳實踐: // - 只在 test 和 檔名匹配 中使用正則表示式 // - 在 include 和 exclude 中使用絕對路徑陣列 // - 儘量避免 exclude,更傾向於使用 include use: ['file-loader'], // options: { // name: "[hash:10].[ext]" //名字太長進行擷取 // } } ] }, resolve: { extensions: ['.js', '.json'] }, /* source-map:外聯 inline-source-map : */ devtool: "source-map", //告訴webpack提供原始碼 plugins: [ // 將CSS檔案從JS檔案中提取出來 new MiniCssExtarctPlugin({ filename: 'css/[name].[contenthash:10].css', path: path.resolve(__dirname, OUTPUT_FILE_NAME) }), new HtmlWebpackPlugin({ template: "./src/index.html" }) ], devServer: { port: 5000, //埠號 contentBase: OUTPUT_FILE_NAME, //可訪問問檔案 hot: true, //開啟HMR熱更新 https: true, //使用https compress: true, // 啟用壓縮 // proxy: { // "/": "http://localhost:3000", //使用代理路徑 // } }, /** code splitting 程式碼分割 * 當單入口時,可以將 node_modules中程式碼單獨打包成一個chunk; * 當多入口時,提取公共檔案單獨打包成一個chunk; */ optimization: { splitChunks: { chunks: "all" } } /** * 快取: * Babel快取 * cacheDirectory:true * -->讓第二次打包更快 * 檔案資源快取: * hash :每次webpack構建是會生成一個唯一的hash值; * 問題:js和css使用同一個hash值,會導致快取失效,可能值改變一個檔案; * chunkhash:根據chunk生成的hash值,如果打包來自同一個chunk,那麼hash是一樣的 * 問題:chunkhash是一樣的,因為css是在js中被引用的,屬於同一個chunk; * contenthash:根據檔案內容生成hash值,不同檔案的hash值不一樣; * -->讓程式碼上線執行快取更好使用 * */ /** * tree shaking:去除無用程式碼 * 前提: 1.必須使用ES6模組化 2.開啟production環境 * 作用: 減少程式碼體積 * * 在package.json中設定: * sideEffects:false 所有程式碼都沒有副作用(都可以進行tree shaking) * 問題:可能會把css @babel/polyfill(副作用)檔案幹掉 * sideEffects:["*.css",".less"] 不會進行tree shaking */ /** * HMR :hot module replacement 熱模組 * 作用:一個模組發生變化指揮重新打包這個模組,並不重新打包所有。提高打包速度。 * 樣式檔案:可以通過HMR實現,style-loader已實現 * JS檔案:預設不使用HMR功能-->修改JS檔案程式碼,只能處理非入口檔案。 * if(module.hot){ * module.hot.accept("index.js",()=>{ * //監聽檔案變化,一旦發生變法,其他地方不會重新打包,直接執行回撥 * })) * } * Html檔案:預設不使用HMR功能,同時會出問題(無需做HMR功能) * 解決方案:修改entry入口,引入html檔案 * * */ }
wenpack.config.pro.js
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtarctPlugin = require("mini-css-extract-plugin"); //將css從js中提取出來 const OptiminizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); //壓縮CSS const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const OUTPUT_FILE_NAME = "dist"; module.exports = { entry: "./src/index.js", output: { filename: "js/[name].[contenthash:10].js", //輸出檔名稱,hash解決快取問題,具體可見下面的解釋 chunkFilename: 'js/[name].[contenthash:10].bundle.js', // 依賴檔名稱 path: path.resolve(__dirname, OUTPUT_FILE_NAME), //輸出檔案路徑 publicPath: '/' // 公共路徑 }, mode: "production", //生產環境 module: { rules: [{ test: /\.html$/, use: ["html-loader"] }, { test: /\.css$/, use: [MiniCssExtarctPlugin.loader, "css-loader"] }, { test: /\.jsx?$/, exclude: /node_modules/, //處理除了nodde_modules裡的js檔案 loader: 'babel-loader' //用babel-loader處理es6 }, { test: /\.(png|svg|jpg|gif)$/, use: ['file-loader'], } ] }, devtool: "source-map", //告訴webpack提供原始碼 plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", hash: true }), new MiniCssExtarctPlugin({ filename: 'css/[name].[contenthash:10].css', path: path.resolve(__dirname, OUTPUT_FILE_NAME) }), /** * optimize-css-assets-webpack-plugin 會使webpack中自帶的JS壓縮失效,需要重新配置UglifyJsPlugin */ new OptiminizeCssAssetsPlugin(), ], /** code splitting 程式碼分割 * 當單入口時,可以將 node_modules中程式碼單獨打包成一個chunk; * 當多入口時,提取公共檔案單獨打包成一個chunk; */ optimization: { splitChunks: { chunks: "all" } } }