一網打盡──Webpack工程打包之一
本文轉載自微信公眾號「前端萬有引力」,作者 一川 。轉載本文請聯系前端萬有引力公眾號。
1.webpack的基本概念
1.1 webpack是什么?
webpack是一個現代js應用程序的靜態模塊打包器(module bundler),一種前端資源構建工具。
- 什么是前端資源構建工具?在瀏覽器中是不認識sass、less、ts等web資源和js高級語法,只有通過webpack這樣的構建工具來將它們一一編譯成瀏覽器能夠讀取的js文件。
- 什么是靜態資源打包器?在webpack處理應用程序時,它會遞歸構建一個依賴關系圖,將應用程序需要的所有模塊打包成一個或多個bundle。
1.2 webpack可以用來做什么?
webpack作為前端工程師最常用的前端資源構建工具,能夠解決很多在開發中的遇到的痛點和難點。
- 可以不依賴后端,解決調用后端接口時的跨域問題
- 在代碼改動后自動刷新瀏覽器,有緩存時也無需清除緩存
- 可以方便解決css和js新特性在各瀏覽器上的兼容性問題,提高自己的開發效率
- 無需使用額外的打包平臺和編寫打包腳本,也無需單獨對js、css等進行打包壓縮
當然,webpack的強大不止這些,它有很多簡單方便的配置能夠提升你的開發效率。
2. webpack的核心配置
常用的核心配置如下:
- 入口 entry
- 輸出 output
- 加載器 loader
- 插件 plugin
- 模式 mode
- 其它配置等
當然,以上列舉的是常用的配置,其它的需求可以查找官方文檔進行閱讀:[https://webpack.docschina.org/concepts/]
2.1 入口 entry
入口(entry)毫無疑問指的是webpack以哪個或哪些文件作為打包的起點,以哪個模塊來構建內部依賴圖。webpack會根據依賴圖去分析各個模塊之間的依賴關系,從而進行打包。
- //單文件入口,string形式:打包形成一個chunk,輸出一個bundle文件,當然在實際開發中的靈活性不大
- entry:"./src/index.js"
- //多文件入口,array形式:所有文件最終形成一個chunck,輸出一個bundle文件
- entry:["./src/index.js","./src/main.js"]
- //多文件入口,object形式:多個入口文件就形成多個chunk,最終輸出多個bundle文件,而chunk的名稱就是對象的key值.雖然這種方式比較繁瑣,但是其擴展性比較強,配置可以重復使用,也可以配合其它配置組合使用。
- entry:{
- index:"./src/index.js",
- main:"./src/main.js"
- }
當然在描述入口的對象的時候,還有許多其它配置屬性,具體可以查看文檔。
- dependOn: 當前入口所依賴的入口。它們必須在該入口被加載前被加載。
- filename: 指定要輸出的文件名稱。
- import: 啟動時需加載的模塊。
- library: 指定 library 選項,為當前 entry 構建一個 library。
- runtime: 運行時 chunk 的名字。如果設置了,就會創建一個新的運行時 chunk。在 webpack 5.43.0 之后可將其設為 false 以避免一個新的運行時 chunk。
- publicPath: 當該入口的輸出文件在瀏覽器中被引用時,為它們指定一個公共 URL 地址。請查看 output.publicPath。
2.2 輸出 output
輸出(output)顯而易見就是告訴webpack在哪里輸出打包后的資源bundles,以及如何命名這些輸出文件。當然主要文件默認為"./dist/main.js",其它文件則放在"./dist"文件夾中。
- // 打包出口
- output:{
- // 輸出文件夾路徑
- path:path.resolve(__dirname,"dist"),
- // 文件名
- // filename:"bundle.js"
- // 如果多個入口起點,應當使用占位符確保每個文件具有唯一名稱
- filename:"[name].js",
- // 所有資源引入公共路徑前綴,用于生產環境需謹慎
- publicPath:"",//編譯時,不知道其輸出文件的地址,則將其置空,在運行時通過入口起點文件的__webpack_public_path__進行動態配置。
- chunkFilename: "[contenthash:10].chunk.js",
- clean: true, //打包前清空輸出目錄,相當于clean-webpack-plugin插件的作用。
- /* 當用 Webpack 去構建一個可以被其他模塊導入使用的庫時需要用到library */
- library: {
- name: "[name]",//整個庫向外暴露的變量名
- type: "window"//庫暴露的方式
- }
- }
切記:即使可以存在多個 entry 起點,但只能指定一個 output 配置。
2.3 加載器 loader
正如你所知道的,webpack只能解析js和json文件,這是其天生自帶的能力。而loader的能力就是讓webpack可以去處理其它類型的文件,將其轉為webpack能夠解析的模塊文件js或json,以提供給應用程序使用,生成到依賴圖中。
- // 加載器
- loader:{
- // 匹配文件類型,服從正則表達式語法
- test:/\.css/,
- // 定義在轉換時,使用到哪些loader,自下而上、自右至左進行處理
- use:[
- "style-loader",//創建style標簽,將js文件中的樣式資源提取出來,添加到index.html文件的head標簽中
- "css-loader",//將css文件轉變成commonjs格式加載到js文件中
- {
- loader:"postcss-loader",//css的兼容性處理,切記:需要預先在package.json文件中配置browserlist
- options:{
- postcssOptions:{
- ident:"postcss",
- // postcss-preset-env插件:幫postcss找到package.json中的browserslist配置,根據配置加載指定的兼容性樣式
- plugins:[require("postcss-preser-env")()]
- }
- }
- }
- ]
- },
- {
- test: /\.js$/,
- // 注意需要在package.json配置browserslist,否則babel-loader不生效
- // js兼容處理 babel
- loader: "babel-loader",
- // 規則只使用一個loader時推薦寫法
- options: {
- presets: [
- [
- "@babel/preset-env",
- // 預設:指示babel做怎么樣的兼容處理
- {
- useBuiltIns: "usage",
- //按需加載
- corejs: {
- version: "3",
- },
- targets: "defaults",
- }
- ]
- ]
- }
- }
2.4 插件 plugin
插件plugin:插件其實就是輔助loader去執行范圍更廣的人物,從打包優化、文件壓縮、資源管理以及重新注入環境變量。
- // CleanWebpackPlugin幫助你在打包時自動清除dist文件,學習時使用比較方便
- // const { CleanWebpackPlugin } = require("clean-webpack-plugin"); //從webpack5開始,webpack內置了該功能,只要在ouput中配置clear為true即可
- // HtmlWebpackPlugin幫助你創建html文件,并自動引入打包輸出的bundles文件。支持html壓縮。
- const HtmlWebpackPlugin = require("html-webpack-plugin");
- // 該插件將CSS提取到單獨的文件中。它會為每個chunk創造一個css文件。需配合loader一起使用
- const MiniCssExtractPlugin = require("mini-css-extract-plugin");
- // 該插件將在Webpack構建過程中搜索CSS資源,并優化\最小化CSS
- const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
- // vue-loader V15版本以上,需要引入VueLoaderPlugin插件,它的作用是將你定義過的js、css等規則應用到vue文件中去。
- const { VueLoaderPlugin } = require('vue-loader')
- module.exports = {
- module: {
- rules: [
- {
- test: /\.vue$/,
- loader: "vue-loader"
- },
- {
- test: /\.css$/,
- use: [
- // MiniCssExtractPlugin.loader的作用就是把css-loader處理好的樣式資源(js文件內),單獨提取出來 成為css樣式文件
- MiniCssExtractPlugin.loader,//生產環境下使用,開發環境還是推薦使用style-loader
- "css-loader",
- ],
- },
- ],
- },
- plugins: [
- new HtmlWebpackPlugin({
- template:"index.html"
- }),
- new MiniCssExtractPlugin({
- filename: "css/built.css",
- }),
- new OptimizeCssAssetsWebpackPlugin(),
- new VueLoaderPlugin(),
- ]
- }
2.5 模式
模式mode用于告知webpack需要使用對應環境模式下的配置,可以是production、development或者none,當然默認是production。
使用mode模式有兩種方式,可以是在配置對象中設置mode選項。
- module.exports = {
- mode:"development"
- }
也可以是在package.json中的cli進行配置:
- webpack --mode=development
官方文檔中是這樣寫的:
選項 | 描述 |
---|---|
development |
會將 DefinePlugin 中 process.env.NODE_ENV 的值設置為 development . 為模塊和 chunk 啟用有效的名。 |
production |
會將 DefinePlugin 中 process.env.NODE_ENV 的值設置為 production 。為模塊和 chunk 啟用確定性的混淆名稱,FlagDependencyUsagePlugin ,FlagIncludedChunksPlugin ,ModuleConcatenationPlugin ,NoEmitOnErrorsPlugin 和 TerserPlugin 。 |
none |
不使用任何默認優化選項 |
如果要根據 webpack.config.js 中的 mode 變量更改打包行為,則必須將配置導出為函數,而不是導出對象:
- ar config = {
- entry: './app.js',
- //...
- };
- module.exports = (env, argv) => {
- if (argv.mode === 'development') {
- config.devtool = 'source-map';
- }
- if (argv.mode === 'production') {
- //...
- }
- return config;
- };
其它常用配置:
- module.exports = {
- // 解析模塊的規則:
- resolve: {
- // 配置 解析模塊路徑別名:可簡寫路徑。
- alias: {
- "@": path.resolve(__dirname, "src")
- },
- // 配置 省略文件路徑的后綴名。默認省略js和json。也是webpack默認認識的兩種文件類型
- extensions: [".js", ".json", ".css"], // 新加css文件
- // 告訴webpack解析模塊是去找哪個目錄
- // 該配置明確告訴webpack,直接去上一層找node_modules。
- modules: [path.resolve(__dirname, "../node_modules")],
- },
- // devServer(開發環境下配置):
- devServer: {
- // 運行代碼的目錄
- contentBase: path.resolve(__dirname, "build"),
- // 為每個靜態文件開啟gzip壓縮
- compress: true,
- host: "localhost",
- port: 5000,
- open: true, // 自動打開瀏覽器
- hot: true, //開啟HMR功能
- // 設置代理
- proxy: {
- // 一旦devServer(5000端口)接收到/api/xxx的請求,就會用devServer起的服務把請求轉發到另外一個服務器(3000)
- // 以此來解決開發中的跨域問題
- api: {
- target: "htttp://localhost:3000",
- // 發送請求時,請求路徑重寫:將/api/xxx --> /xxx (去掉/api)
- pathRewrite: {
- "^api": "",
- },
- },
- },
- },
- // optimization(生產環境下配置)
- optimization: {
- // 提取公共代碼
- splitChunks: {
- chunks: "all",
- },
- minimizer: [
- // 配置生產環境的壓縮方案:js和css
- new TerserWebpackPlugin({
- // 多進程打包
- parallel: true,
- terserOptions: {
- // 啟動source-map
- sourceMap: true,
- },
- }),
- ],
- },
- };
3參考文章
webpack官方文檔
Webpack5.0學習總結-基礎篇