亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

從基礎(chǔ)到實(shí)戰(zhàn) 手摸手帶你掌握新版Webpack4.0詳解 一起讀文檔

王軍 / 3083人閱讀

摘要:構(gòu)建構(gòu)建就是把源代碼轉(zhuǎn)換成發(fā)布到線上的可執(zhí)行代碼,包括如下內(nèi)容。自動(dòng)刷新監(jiān)聽(tīng)本地源代碼的變化,自動(dòng)重新構(gòu)建刷新瀏覽器。自動(dòng)發(fā)布更新完代碼后,自動(dòng)構(gòu)建出線上發(fā)布代碼并傳輸給發(fā)布系統(tǒng)。將文件放入到項(xiàng)目中,在中新建一個(gè)放字體圖標(biāo)的文件夾。

項(xiàng)目地址 github.com/wudiufo/Web…

知識(shí)點(diǎn)概覽:

Loader,HMR ,Create React App, Caching, Plugin, SourceMap,Vue Cli 3.0 ,Shimming, WebpackDevServer,TreeShaking, CodeSplitting, Babel, React , Library, Eslint ,PWA, Vue, Mode,性能優(yōu)化,多頁(yè)應(yīng)用,原理, PreLoading, PreFetching ,環(huán)境變量,TypeScript

收獲:

徹底學(xué)會(huì)Webpack的配置 理解 Webpack的作用及原理 上手項(xiàng)目的打包過(guò)程配置 擁有工程化的前端思維 步入高級(jí)前端工程師行列

一:初識(shí)Webpack

官網(wǎng)圖鎮(zhèn)樓:

1. 1 什么是WebPack

webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包工具:它做的事情是,分析你的項(xiàng)目結(jié)構(gòu),找到JavaScript模塊以及其它的一些瀏覽器不能直接運(yùn)行的拓展語(yǔ)言(Scss,TypeScript等),并生成一個(gè)或多個(gè) bundle,將其打包為合適的格式以供瀏覽器使用。

webpack構(gòu)建:

構(gòu)建就是把源代碼轉(zhuǎn)換成發(fā)布到線上的可執(zhí)行 JavaScrip、CSS、HTML 代碼,包括如下內(nèi)容。

1.代碼轉(zhuǎn)換:TypeScript 編譯成 JavaScript、SCSS或Less 編譯成 CSS 等。

2.文件優(yōu)化:壓縮 JavaScript、CSS、HTML 代碼,壓縮合并圖片等。

3.代碼分割:提取多個(gè)頁(yè)面的公共代碼、提取首屏不需要執(zhí)行部分的代碼讓其異步加載。

4.模塊合并:在采用模塊化的項(xiàng)目里會(huì)有很多個(gè)模塊和文件,需要構(gòu)建功能把模塊分類合并成一個(gè)文件。

5.自動(dòng)刷新:監(jiān)聽(tīng)本地源代碼的變化,自動(dòng)重新構(gòu)建、刷新瀏覽器,nodemon。

6.代碼校驗(yàn):在代碼被提交到倉(cāng)庫(kù)前需要校驗(yàn)代碼是否符合規(guī)范,以及單元測(cè)試是否通過(guò)。

7.自動(dòng)發(fā)布:更新完代碼后,自動(dòng)構(gòu)建出線上發(fā)布代碼并傳輸給發(fā)布系統(tǒng)。

構(gòu)建其實(shí)是工程化、自動(dòng)化思想在前端開(kāi)發(fā)中的體現(xiàn),把一系列流程用代碼去實(shí)現(xiàn),讓代碼自動(dòng)化地執(zhí)行這一系列復(fù)雜的流程。 構(gòu)建給前端開(kāi)發(fā)注入了更大的活力,解放了我們的生產(chǎn)力,更加方便了我們的開(kāi)發(fā)。

1.2 什么是 webpack 模塊

ES2015 import 語(yǔ)句

CommonJS require() 語(yǔ)句

AMD definerequire 語(yǔ)句

css/sass/less 文件中的 @import 語(yǔ)句。

樣式(url(...))或 HTML 文件()中的圖片鏈接

詳細(xì)請(qǐng)看官網(wǎng)文檔:Modules MODULES

1.3 搭建Webpack環(huán)境

去官網(wǎng)下載node

// 查看node版本號(hào)
node -v
// 查看npm版本號(hào)
npm -v

1.4 初始化項(xiàng)目
mkdir webpack-productname
cd webpack-productname 
//初始化webpack配置清單package.json
npm init -y   
1.5 安裝webpack
//全局安裝(不推薦),因?yàn)槿绻袃蓚€(gè)項(xiàng)目用了webpack不同版本,就會(huì)出現(xiàn)版本不統(tǒng)一運(yùn)行不起來(lái)的情況。只有卸了當(dāng)前版本安裝對(duì)應(yīng)版本非常麻煩。
npm install webpack webpack-cli -g
//查看版本
webpack -v
//全局卸載
npm uninstall webpack webpack-cli -g
//在項(xiàng)目里安裝webpack(推薦使用)??梢栽诓煌?xiàng)目中使用不同的webpack版本。
cd webpack-productname
npm install webpack webpack-cli -D
//查看版本
npx webpack -v
//查看對(duì)應(yīng)包的詳細(xì)信息
npm info webpack
//安裝指定版本包
npm install webpack@4.16.1 webpack-cli -D

注意:

由于npm安裝走的是國(guó)外的網(wǎng)絡(luò),比較慢容易出現(xiàn)安裝失敗的現(xiàn)象。

可以用yarn安裝,首先得全局安裝yarn,npm install yarn -g

或使用nrm快速切換npm源,首先得全局安裝nrm, npm install -g nrm。

nrm 使用:

nrm ls 查看可選源。

nrm test npm 測(cè)試速度。看哪個(gè)快就use哪個(gè)。

nrm use cnpm 使用cnpm 。

webpack-cli:使我們們可以在命令行里正確的使用webpack

1.6 webpack的配置文件

webpack 開(kāi)箱即用,可以無(wú)需使用任何配置文件。然而,webpack 會(huì)假定項(xiàng)目的入口起點(diǎn)為 src/index,然后會(huì)在 dist/main.js 輸出結(jié)果,并且在生產(chǎn)環(huán)境開(kāi)啟壓縮和優(yōu)化。通常,你的項(xiàng)目還需要繼續(xù)擴(kuò)展此能力,為此你可以在項(xiàng)目根目錄下創(chuàng)建一個(gè) webpack.config.js 文件,webpack 會(huì)自動(dòng)使用它。

在項(xiàng)目根目錄下創(chuàng)建 webpack.config.js 文件,這是webpack默認(rèn)配置文件

const path = require("path")

module.exports = {
    //默認(rèn)是production,打包的文件默認(rèn)被壓縮。開(kāi)發(fā)時(shí)可以設(shè)置為development,不被壓縮
    mode:"production", 
    //打包項(xiàng)目的入口文件
    entry: "./index.js",
    //打包項(xiàng)目的輸出文件
    output: {
        //自定義打包輸出文件名
        filename:"bundle.js",
        //輸出文件的絕對(duì)路徑
        path: path.resolve(__dirname,"bundle")
    }
}

也可以自己指定配置文件來(lái)完成webpack的打包:

npx webpack --config + 自定義配置文件

詳細(xì)請(qǐng)看官方文檔:概念 配置

1.7 webpack打包輸出內(nèi)容
執(zhí)行 `npm run build` 后,在控制臺(tái)輸出

Hash:1b245e275a547956bf52 //本次打包對(duì)應(yīng)唯一一個(gè)hash值
Version:webpack 4.29.6 //本次打包對(duì)應(yīng)webpack版本
Time:162ms Built at:2019-4-11 23:13:43 //本次打包耗時(shí),及打包的時(shí)間
Asset Size Chunks Chunk Names //打包后的文件名,大小,id,入口文件名
bundle.js 1.36 KiB 0 [emitted] main 
Entrypoint main=bundle.js
[0]./src/index.js 159 bytes {0}[built]
[1]./src/header.js 187 bytes {e}[built]
[2]./src/sidebar.js 193 bytes {e}[built]
[3]./src/content.js 193 bytes {e} [built]

二:Webpack核心概念 LOADER 2.1 什么是Loader

webpack可以使用 loader 來(lái)預(yù)處理文件,就是通過(guò)使用不同的Loader,webpack可以把不同的靜態(tài)文件都編譯成js文件,比如css,sass,less,ES6/7,vue,JSX等。

使用Loader打包靜態(tài)資源

支持加載圖片文件

需要安裝 file-loader:解決CSS等文件中的引入圖片路徑問(wèn)題

 npm install file-loader -D

webpack.config.js 里添加 loader 配置

module.exports = {
    //配置模塊,主要用來(lái)配置不同文件的加載器
  module: {
      //配置模塊規(guī)則
    rules: [
      {
        test: /.(png|jpg|gif)$/, //正則匹配要使用相應(yīng)loader的文件
        use: [
          {
            loader: "file-loader", //要用到的loader
              options: {
                  //palceholder占位符
                  name:"[name].[ext]", //打包后的圖片名字,后綴和打包的之前的圖片一樣
                  outputPath: "images/" //圖片打包后的地址
              },
          },
        ],
      },
    ],
  },
};

詳細(xì)請(qǐng)看官方文檔:file-loader

將小圖片轉(zhuǎn)換成base64格式

需要安裝 url-loader:當(dāng)圖片小于limit的時(shí)候會(huì)把圖片BASE64編碼,大于limit參數(shù)的時(shí)候還是使用file-loader 進(jìn)行拷貝

npm install url-loader -D

webpack.config.js 里添加 loader 配置

module.exports = {
  module: {
    rules: [
      {
        test: /.(png|jpg|gif|bmp/)$/i,
        use: [
          {
            loader: "url-loader",
            options: {
              name:"[name].[ext]",
              outputPath: "images/",
              limit: 8192 //小于8192b,就可以轉(zhuǎn)化成base64格式。大于就會(huì)打包成文件格式
            }
          }
        ]
      }
    ]
  }
}

詳細(xì)請(qǐng)看官方文檔:url-loader


支持加載樣式CSS文件

需要安裝 css-loader style-loader:

npm install css-loader style-loader -D

webpack.config.js 里添加 loader 配置

module.exports = {
  module: {
    rules: [
      {
        test: /.css$/, //匹配以css為后綴的文件
        use: ["style-loader", "css-loader"],//loader的執(zhí)行順序是從右向左,從下到上。css-loader:分析幾個(gè)css文件之間的關(guān)系,最終合并為一個(gè)css。style-loader:在得到css生成的內(nèi)容時(shí),把其掛載到html的head里,成為內(nèi)聯(lián)樣式。
      },
    ],
  },
};

支持加載樣式SASS文件

需要安裝 sass-loader node-sass:

npm install sass-loader node-sass -D

webpack.config.js 里添加 loader 配置

module.exports = {
    ...
    module: {
        rules: [{
            test: /.scss$/,
            use: [
                "style-loader", // 將 JS 字符串生成為 style 節(jié)點(diǎn)
                "css-loader", // 將 CSS 轉(zhuǎn)化成 CommonJS 模塊
                "sass-loader" // 將 Sass 編譯成 CSS,默認(rèn)使用 Node Sass
            ]
        }]
    }
};

為 css 樣式屬性加不同瀏覽器的前綴

為了瀏覽器的兼容性,有時(shí)候我們必須加入-webkit,-ms,-o,-moz這些前綴

Trident內(nèi)核:主要代表為IE瀏覽器, 前綴為-ms

Gecko內(nèi)核:主要代表為Firefox, 前綴為-moz

Presto內(nèi)核:主要代表為Opera, 前綴為-o

Webkit內(nèi)核:產(chǎn)要代表為Chrome和Safari, 前綴為-webkit

npm i postcss-loader autoprefixer -D

在項(xiàng)目跟目錄下創(chuàng)建 postcss.config.js

module.exports = {
    plugins: [
        require("autoprefixer")
    ]
}

webpack.config.js

module.exports = {
    ...
    module: {
        rules: [{
            test: /.scss$/,
            use: [
                "style-loader", // 將 JS 字符串生成為 style 節(jié)點(diǎn)
                "css-loader", // 將 CSS 轉(zhuǎn)化成 CommonJS 模塊
                "postcss-loader",//配置在css-loader后,在sass|less|stylus-loader 之前。
                "sass-loader" // 將 Sass 編譯成 CSS,默認(rèn)使用 Node Sass
                
            ]
        }]
    }
};

給loader加一些配置項(xiàng):

webpack.config.js

module.exports = {
    ...
    module: {
        rules: [{
            test: /.scss$/,
            use: [
                "style-loader", 
                {
                 	loader: "css-loader",
                    options:{
                        importLoaders:2 ,//如果sass文件里還引入了另外一個(gè)sass文件,另一個(gè)文件還會(huì)從sass-loader向上解析。如果不加,就直接從css-loader開(kāi)始解析。// 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
                        modules: true //開(kāi)啟css的模塊打包。css樣式不會(huì)和其他模塊發(fā)生耦合和沖突
                    }
                }, 
                "postcss-loader",
                "sass-loader", 
                
            ]
        }]
    }
};

為字體圖標(biāo)文件配loader

在 阿里巴巴矢量圖標(biāo)庫(kù)中,把需要的字體圖標(biāo)下載到本地,解壓。將iconfont.eot iconfont.svg iconfont.ttf iconfont.woff 文件放入到項(xiàng)目中,在src中新建一個(gè)放字體圖標(biāo)的文件夾font。將iconfont.css文件拷貝到項(xiàng)目中,自己改一下引入字體圖標(biāo)的路徑。

需要安裝 file-loader:

npm i file-loader -D

webpack.config.js

module.exports = {
    ...
    module: {
        rules: [{
            test: /.(eot|ttf|svg|woff)$/,
            use:{
                loader:"file-loader"
            }
        },
            ]
        }]
    }
};

詳細(xì)請(qǐng)看官方文檔:asset-management


plugin : 可以在webpack運(yùn)行到某個(gè)時(shí)刻的時(shí)候,幫你做一些事情

使用plugins讓打包更便捷

HtmlWebpackPlugin :htmlWebpackPlugin 會(huì)在打包結(jié)束后,自動(dòng)生成一個(gè)html文件,并把打包生成的js自動(dòng)引入到這個(gè)html文件中

安裝:npm i html-webpack-plugin -D

基本用法:在 webpack.config.js 中:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

module.exports = {
  entry: "index.js",
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "index_bundle.js"
  },
    plugins: [new HtmlWebpackPlugin({
        template: "src/index.html" //以index.html為模板,把打包生成的js自動(dòng)引入到這個(gè)html文件中
    })]
};

CleanWebpackPlugin :自動(dòng)清除上一次打包的dist文件

安裝:npm i clean-webpack-plugin -D

基本用法:在 webpack.config.js 中:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const path = require("path");

module.exports = {
  entry: "index.js",
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "index_bundle.js"
  },
    plugins: [
        new HtmlWebpackPlugin({
        template: "src/index.html" //在打包之后,以.html為模板,把打包生成的js自動(dòng)引入到這個(gè)html文件中
    }),
        new CleanWebpackPlugin(["dist"]), // 在打包之前,可以刪除dist文件夾下的所有內(nèi)容
    
    ]
};

Entry與Output的基礎(chǔ)配置

在打包多入口文件時(shí)的配置

基本用法:在 webpack.config.js 中:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const path = require("path");

module.exports = {
  entry: {
   	main: "./src/index.js",
    sub: "./src/index.js"
  },
  output: {
    publicPath: "http://cdn.com.cn", //將注入到html中的js文件前面加上地址
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js"
  },
    plugins: [
        new HtmlWebpackPlugin({
        template: "src/index.html" //在打包之后,以.html為模板,把打包生成的js自動(dòng)引入到這個(gè)html文件中
    }),
        new CleanWebpackPlugin(["dist"]), // 在打包之前,可以刪除dist文件夾下的所有內(nèi)容
    
    ]
};

詳細(xì)請(qǐng)看官網(wǎng):Output output-management


SourceMap 的配置

sourcemap:打包編譯后的文件和源文件的映射關(guān)系,用于開(kāi)發(fā)者調(diào)試用。

source-map 把映射文件生成到多帶帶的文件,最完整但最慢

cheap-module-source-map 在一個(gè)多帶帶的文件中產(chǎn)生一個(gè)不帶列映射的Map

eval-source-map 使用eval打包源文件模塊,在同一個(gè)文件中生成完整sourcemap

cheap-module-eval-source-map sourcemap和打包后的JS同行顯示,沒(méi)有映射列

development環(huán)境推薦使用: devtool: "cheap-module-eval-source-map", production環(huán)境推薦使用: devtool: "cheap-module-source-map",

webpack.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");

module.exports = {
	mode: "development",
    devtool: "cheap-module-eval-source-map",
	//devtool:"none",//在開(kāi)發(fā)者模式下,默認(rèn)開(kāi)啟sourcemap,將其關(guān)閉
    //devtool:"source-map"http://開(kāi)啟映射打包會(huì)變慢
    //devtool:"inline-source-map"http://不多帶帶生成.map文件,會(huì)將生成的映射文件以base64的形式插入到打包后的js文件的底部
    //devtool:"cheap-inline-source-map"http://代碼出錯(cuò)提示不用精確顯示第幾行的第幾個(gè)字符出錯(cuò),只顯示第幾行出錯(cuò),會(huì)提高一些性能
    //devtool:"cheap-module-inline-source-map"http://不僅管自己的業(yè)務(wù)代碼出錯(cuò),也管第三方模塊和loader的一些報(bào)錯(cuò)
    //devtool:"eval"http://執(zhí)行效率最快,性能最好,但是針對(duì)比較復(fù)雜的代碼的情況下,提示內(nèi)容不全面
	//devtool: "cheap-module-eval-source-map",//在開(kāi)發(fā)環(huán)境推薦使用,提示比較全,打包速度比較快
    //devtool: "cheap-module-source-map",//在生產(chǎn)環(huán)境中推薦使用,提示效果會(huì)好一些
	
	
	entry: {
		main: "./src/index.js"
	},
	module: {
		rules: [{
			test: /.(jpg|png|gif)$/,
			use: {
				loader: "url-loader",
				options: {
					name: "[name]_[hash].[ext]",
					outputPath: "images/",
					limit: 10240
				}
			} 
		}, {
			test: /.(eot|ttf|svg)$/,
			use: {
				loader: "file-loader"
			} 
		}, {
			test: /.scss$/,
			use: [
				"style-loader", 
				{
					loader: "css-loader",
					options: {
						importLoaders: 2
					}
				},
				"postcss-loader",
				"sass-loader",
				
			]
		}]
	},
	plugins: [new HtmlWebpackPlugin({
		template: "src/index.html"
	}), new CleanWebpackPlugin(["dist"])],
	output: {
		filename: "[name].js",
		path: path.resolve(__dirname, "dist")
	}
}

詳細(xì)請(qǐng)看官網(wǎng):devtool


使用WebpackDevServer 提升開(kāi)發(fā)效率

解決每次在src里編寫(xiě)完代碼都需要手動(dòng)重新運(yùn)行 npm run dev

1.在 package.json 中配置

{
  "name": "haiyang",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "bundle": "webpack",
    "watch": "webpack --watch",// 加--watch自動(dòng)監(jiān)聽(tīng)代碼的變化
    
  },
  
}

2.在 webpack.config.js 中,加 devServer

安裝 npm i webpack-dev-server –D

contentBase :配置開(kāi)發(fā)服務(wù)運(yùn)行時(shí)的文件根目錄

open :自動(dòng)打開(kāi)瀏覽器

host:開(kāi)發(fā)服務(wù)器監(jiān)聽(tīng)的主機(jī)地址

compress :開(kāi)發(fā)服務(wù)器是否啟動(dòng)gzip等壓縮

port:開(kāi)發(fā)服務(wù)器監(jiān)聽(tīng)的端口

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");

module.exports = {
	mode: "development",
	devtool: "cheap-module-eval-source-map",
	entry: {
		main: "./src/index.js"
	},
+	devServer: {
		contentBase: "./dist",
		open: true,
		port: 8080,
    	proxy: {//配置跨域,訪問(wèn)的域名會(huì)被代理到本地的3000端口
      		"/api": "http://localhost:3000"
    	}
	},
	module: {
		rules: []
	},
	plugins: [],
	output: {
		filename: "[name].js",
		path: path.resolve(__dirname, "dist")
	}
}

在 package.json 中:

{
  "name": "haiyang",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "bundle": "webpack",
    "watch": "webpack --watch",// 加--watch自動(dòng)監(jiān)聽(tīng)代碼的變化
    "start": "webpack-dev-server",//配置熱更新
	
  },
 
}

詳細(xì)請(qǐng)看官網(wǎng) :dev-server

擴(kuò)充知識(shí):自己寫(xiě)一個(gè)類似webpackdevserver的工具

了解即可,功能不全,自行擴(kuò)展。

在 package.json 中:

{
  "name": "haiyang",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "bundle": "webpack",
    "watch": "webpack --watch",// 加--watch自動(dòng)監(jiān)聽(tīng)代碼的變化
    "start": "webpack-dev-server",//配置熱更新
+	"server" : "node server.js" //自己寫(xiě)一個(gè)類似webpackdevserver的工具
  },
 
}

安裝 :npm i express webpack-dev-middleware -D

在 項(xiàng)目根目錄下創(chuàng)建 server.js 文件

在 server.js 中

const express = require("express");
const webpack = require("webpack");
const webpackDevMiddleware = require("webpack-dev-middleware");
const config = require("./webpack.config.js");
const complier = webpack(config);

const app = express();

app.use(webpackDevMiddleware(complier, {}));

app.listen(3000, () => {
	console.log("server is running");
});

模塊熱替換(hot module replacement)

在 package.json 中:

{
  "name": "haiyang",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server" //將文件打包到內(nèi)存中,有助于開(kāi)發(fā)
  },
}

在 webpack.config.js 中

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");

module.exports = {
	mode: "development",
	devtool: "cheap-module-eval-source-map",
	entry: {
		main: "./src/index.js"
	},
	devServer: {
		contentBase: "./dist",
		open: true,
		port: 8080,
+		hot: true,//開(kāi)啟熱更新
+		hotOnly: true//盡管html功能沒(méi)有實(shí)現(xiàn),也不讓瀏覽器刷新
	},
	module: {
		rules: [{
			test: /.(jpg|png|gif)$/,
			use: {
				loader: "url-loader",
				options: {
					name: "[name]_[hash].[ext]",
					outputPath: "images/",
					limit: 10240
				}
			} 
		}, {
			test: /.(eot|ttf|svg)$/,
			use: {
				loader: "file-loader"
			} 
		}, {
			test: /.scss$/,
			use: [
				"style-loader", 
				{
					loader: "css-loader",
					options: {
						importLoaders: 2
					}
				},
				"postcss-loader",
				"sass-loader",
				
			]
		}, {
			test: /.css$/,
			use: [
				"style-loader",
				"css-loader",
				"postcss-loader"
			]
		}]
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: "src/index.html"
		}), 
		new CleanWebpackPlugin(["dist"]),
+		new webpack.HotModuleReplacementPlugin() //使用模塊熱更新插件
	],
	output: {
		filename: "[name].js",
		path: path.resolve(__dirname, "dist")
	}
}

index.js

//如果模塊啟用了HMR,就可以用 module.hot.accept(),監(jiān)聽(tīng)模塊的更新。
if (module.hot) {
  module.hot.accept("./library.js", function() {
    // 使用更新過(guò)的 library 模塊執(zhí)行某些操作...
  })
}

注意點(diǎn):

引入css,用框架Vue,React 時(shí),不需要寫(xiě) module.hot.accept(),因?yàn)樵谑褂胏ss-loader,vue-loader,babel-preset時(shí),就已經(jīng)配置好了HMR,不需要自己寫(xiě)

詳細(xì)請(qǐng)看官方文檔:hot-module-replacement api/hot-module-replacement concepts/hot-module-replacement


使用 Babel 處理 ES6/7 語(yǔ)法 轉(zhuǎn)義為ES5

BABEL官網(wǎng):babeljs.io/setup

安裝依賴包:

npm i babel-loader @babel/core @babel/preset-env -D
//生產(chǎn)依賴,兼容低版本瀏覽器
npm install --save @babel/polyfill

在 webpack.config.js 中

module: {
  rules: [
    {
        test: /.js$/,
     	exclude: /node_modules/,//不需要對(duì)第三方模塊進(jìn)行轉(zhuǎn)換,耗費(fèi)性能
     	loader: "babel-loader" ,
        options:{
            "presets": [["@babel/preset-env",{
                targets: {//這個(gè)項(xiàng)目運(yùn)行在大于什么版本的瀏覽器上,已經(jīng)支持es6的語(yǔ)法的高版本瀏覽器就不需要轉(zhuǎn)義成es5了
                    edge: "17",
                    firefox: "60",
                    chrome: "67",
                    safari: "11.1",
                  },
                useBuiltIns:"usage" //按需添加polyfill,把用到的代碼都轉(zhuǎn)成低版本瀏覽器兼容的
            }]]
        }
    }
  ]
}

在 index.js 中:

//在業(yè)務(wù)代碼運(yùn)行之前最頂部導(dǎo)入
import "@babel/polyfill";
注意:在開(kāi)發(fā)類庫(kù),第三方模塊或組件庫(kù)時(shí)不能用 @babel/polyfill 這種方案,因?yàn)闀?huì)把聲明的變量變成全局變量,會(huì)污染全局環(huán)境。

安裝:

npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
npm install --save @babel/runtime-corejs2

在 webpack.config.js 中

module: {
  rules: [
    {
        test: /.js$/,
     	exclude: /node_modules/,//不需要對(duì)第三方模塊進(jìn)行轉(zhuǎn)換,耗費(fèi)性能
     	loader: "babel-loader" ,
        options:{
            "plugins": [["@babel/plugin-transform-runtime",{
                "corejs": 2,
                "helpers": true,
                "regenerator": true,
                "useESModules": false
            }]]
        }
    }
  ]
}

由于babel需要配置的內(nèi)容非常多,我們需要在項(xiàng)目根目錄下創(chuàng)建一個(gè) .babelrc 文件。

就不需要在 webpack.config.js 中寫(xiě) babel 的配置了。

.babelrc 中:

{
            "plugins": [["@babel/plugin-transform-runtime",{
                "corejs": 2,
                "helpers": true,
                "regenerator": true,
                "useESModules": false
            }]]
        }

配置 React 代碼的打包

業(yè)務(wù)代碼:

.babelrc 中:

	{ 
            "presets": [
                ["@babel/preset-env",{
                targets: {
                    edge: "17",
                    firefox: "60",
                    chrome: "67",
                    safari: "11.1",
                  },
                useBuiltIns:"usage" 
            		}
                ],
                "@babel/preset-react"
            ]
        }
//執(zhí)行順序:從下往上,從右向左的順序

安裝:

npm i react react-dom --save
npm install --save-dev @babel/preset-react

詳細(xì)內(nèi)容請(qǐng)看官網(wǎng):babel-loader


三:Webpack進(jìn)階 Tree Shaking:只支持 ES Module 例如 importexport 的靜態(tài)結(jié)構(gòu)特性的引入。當(dāng)引入一個(gè)模塊時(shí),不引入所有的代碼,只引入需要的代碼

在 webpack.config.js 中:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");

module.exports = {
	mode: "development",
	devtool: "cheap-module-eval-source-map",
	entry: {
		main: "./src/index.js"
	},
	devServer: {
		contentBase: "./dist",
		open: true,
		port: 8080,
		hot: true,
		hotOnly: true
	},
	module: {
		rules: []
	},
	plugins: [],
+	optimization: { //在開(kāi)發(fā)環(huán)境中加,生產(chǎn)環(huán)境不加
		usedExports: true
	},
	output: {
		filename: "[name].js",
		path: path.resolve(__dirname, "dist")
	}
}

在 package.json 中:

{
+ "sideEffects": ["*.css"], //對(duì) 所有的css文件 不使用Tree shaking。如果填 false,就是都需要用到Tree shaking
}

詳細(xì)內(nèi)容請(qǐng)看官網(wǎng):tree-shaking


Develoment 和Production模式的區(qū)分打包

在項(xiàng)目根目錄下創(chuàng)建兩個(gè)文件,webpack.dev.js,webpack.prod.js

webpack.dev.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");

module.exports = {
	mode: "development",
	devtool: "cheap-module-eval-source-map",
	entry: {
		main: "./src/index.js"
	},
	devServer: {
		contentBase: "./dist",
		open: true,
		port: 8080,
		hot: true,
		hotOnly: true
	},
	module: {
		rules: [{ 
			test: /.js$/, 
			exclude: /node_modules/, 
			loader: "babel-loader",
		}, {
			test: /.(jpg|png|gif)$/,
			use: {
				loader: "url-loader",
				options: {
					name: "[name]_[hash].[ext]",
					outputPath: "images/",
					limit: 10240
				}
			} 
		}, {
			test: /.(eot|ttf|svg)$/,
			use: {
				loader: "file-loader"
			} 
		}, {
			test: /.scss$/,
			use: [
				"style-loader", 
				{
					loader: "css-loader",
					options: {
						importLoaders: 2
					}
				},
				"postcss-loader",
				"sass-loader",
				
			]
		}, {
			test: /.css$/,
			use: [
				"style-loader",
				"css-loader",
				"postcss-loader"
			]
		}]
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: "src/index.html"
		}), 
		new CleanWebpackPlugin(["dist"]),
		new webpack.HotModuleReplacementPlugin()
	],
	optimization: {
		usedExports: true
	},
	output: {
		filename: "[name].js",
		path: path.resolve(__dirname, "dist")
	}
}

webpack.prod.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");

module.exports = {
	mode: "production",
	devtool: "cheap-module-source-map",
	entry: {
		main: "./src/index.js"
	},
	
	module: {
		rules: [{ 
			test: /.js$/, 
			exclude: /node_modules/, 
			loader: "babel-loader",
		}, {
			test: /.(jpg|png|gif)$/,
			use: {
				loader: "url-loader",
				options: {
					name: "[name]_[hash].[ext]",
					outputPath: "images/",
					limit: 10240
				}
			} 
		}, {
			test: /.(eot|ttf|svg)$/,
			use: {
				loader: "file-loader"
			} 
		}, {
			test: /.scss$/,
			use: [
				"style-loader", 
				{
					loader: "css-loader",
					options: {
						importLoaders: 2
					}
				},
				"postcss-loader",
				"sass-loader",
				
			]
		}, {
			test: /.css$/,
			use: [
				"style-loader",
				"css-loader",
				"postcss-loader"
			]
		}]
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: "src/index.html"
		}), 
		new CleanWebpackPlugin(["dist"]),
		
	],
	
	output: {
		filename: "[name].js",
		path: path.resolve(__dirname, "dist")
	}
}

在 package.json 中:

{
  "scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },
}

解決 webpack.dev.js,webpack.prod.js 存在大量重復(fù)代碼,在項(xiàng)目根目錄下創(chuàng)建一個(gè) webpack.common.js 文件,把公共代碼提取出來(lái)

安裝 :

npm i webpack-merge -D 

webpack.common.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");

module.exports = {

	entry: {
		main: "./src/index.js"
	},
	
	module: {
		rules: [{ 
			test: /.js$/, 
			exclude: /node_modules/, 
			loader: "babel-loader",
		}, {
			test: /.(jpg|png|gif)$/,
			use: {
				loader: "url-loader",
				options: {
					name: "[name]_[hash].[ext]",
					outputPath: "images/",
					limit: 10240
				}
			} 
		}, {
			test: /.(eot|ttf|svg)$/,
			use: {
				loader: "file-loader"
			} 
		}, {
			test: /.scss$/,
			use: [
				"style-loader", 
				{
					loader: "css-loader",
					options: {
						importLoaders: 2
					}
				},
				"postcss-loader",
				"sass-loader",
				
			]
		}, {
			test: /.css$/,
			use: [
				"style-loader",
				"css-loader",
				"postcss-loader"
			]
		}]
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: "src/index.html"
		}), 
        new CleanWebpackPlugin(["dist"],{
            root:path.resolve(__dirname,"../")
        }),
		
	],
	
	output: {
		filename: "[name].js",
		path: path.resolve(__dirname, "../dist")
	}
}

webpack.dev.js

const webpack = require("webpack");
const merge = require("webpack-merge")
const commenConfig = require("./webpack.commin.js")

const devConfig = {
	mode: "development",
	devtool: "cheap-module-eval-source-map",
	
	devServer: {
		contentBase: "./dist",
		open: true,
		port: 8080,
		hot: true,
		hotOnly: true
	},
	
	plugins: [	
		new webpack.HotModuleReplacementPlugin()
	],
	optimization: {
		usedExports: true
	},	
}
//將開(kāi)發(fā)配置和公共配置做結(jié)合
module.exports = merge(commenConfig, devConfig)

webpack.prod.js

const merge = require("webpack-merge")
const commenConfig = require("./webpack.commin.js")

const prodConfig = {
	mode: "production",
	devtool: "cheap-module-source-map",
}
//將線上配置和公共配置做結(jié)合
module.exports = merge(commenConfig, prodConfig)

最后在根目錄下創(chuàng)建一個(gè)build文件夾,將 webpack.common.js , webpack.dev.js ,webpack.prod.js 放在build文件夾下,統(tǒng)一管理。

在 package.json 中:

{
  "scripts": {
    "dev": "webpack-dev-server --config ./build/webpack.dev.js",
    "build": "webpack --config ./build/webpack.prod.js"
  },
}

詳細(xì)請(qǐng)看官網(wǎng)文檔:guides/production


Webpack和Code Splitting

安裝: npm i lodash --save npm i babel-plugin-dynamic-import-webpack -D

代碼分割,和webpack無(wú)關(guān),為了提升性能 webpack中實(shí)現(xiàn)代碼分割,兩種方式:

第一種方法:同步代碼: 只需要在webpack.common.js中做optimization的配置即可

第二種方法:異步代碼(import): 異步代碼,無(wú)需做任何配置,會(huì)自動(dòng)進(jìn)行代碼分割,放置到新的文件中

第一種方法:在 webpack.common.js 中

module.exports = {
	entry: {
		main: "./src/index.js"
	},
	
	module: {
		rules: []
	},
	plugins: [],
+    optimization:{
+       splitChunks:{ //啟動(dòng)代碼分割,有默認(rèn)配置項(xiàng)
+            chunks:"all"
+        }  
+    },
	
	output: {}
}

第二種方法在 .babelrc 中:

{
	presets: [
		[
			"@babel/preset-env", {
				targets: {
					chrome: "67",
				},
				useBuiltIns: "usage"
			}
		],
		"@babel/preset-react"
	],
+	plugins: ["dynamic-import-webpack"]
}

詳細(xì)內(nèi)容請(qǐng)看官網(wǎng):code-splitting


SplitChunksPlugin 配置參數(shù)詳解

安裝:npm install --save-dev @babeL/plugin-syntax-dynamic-import

在業(yè)務(wù) index.js 中:

 function getComponent() {
 	return import(/* webpackChunkName:"lodash" */ "lodash").then(({ default: _ }) => {
 		var element = document.createElement("div");
		element.innerHTML = _.join(["1", "2"], "-");
 		return element;
	})
}

 getComponent().then(element => {
 	document.body.appendChild(element);
 });

.babelrc 中:

{
	presets: [
		[
			"@babel/preset-env", {
				targets: {
					chrome: "67",
				},
				useBuiltIns: "usage"
			}
		],
		"@babel/preset-react"
	],
+	plugins: ["@babeL/plugin-syntax-dynamic-import"]
}

在 webpack.common.js 中:

module.exports = {
	entry: {
		main: "./src/index.js"
	},
	
	module: {
		rules: []
	},
	plugins: [],
+    optimization:{
+       splitChunks:{ //啟動(dòng)代碼分割,不寫(xiě)有默認(rèn)配置項(xiàng)
+            chunks: "all",//參數(shù)all/initial/async,只對(duì)所有/同步/異步進(jìn)行代碼分割
              minSize: 30000, //大于30kb才會(huì)對(duì)代碼分割
              maxSize: 0,
              minChunks: 1,//打包生成的文件,當(dāng)一個(gè)模塊至少用多少次時(shí)才會(huì)進(jìn)行代碼分割
              maxAsyncRequests: 5,//同時(shí)加載的模塊數(shù)最多是5個(gè)
              maxInitialRequests: 3<           
               
                                           
                       
                 

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/7340.html

相關(guān)文章

  • webpack 基礎(chǔ)與項(xiàng)目?jī)?yōu)化實(shí)踐總結(jié)

    摘要:前言本文基于,主要涉及基本概念基本配置和實(shí)際項(xiàng)目打包優(yōu)化。關(guān)于概念方面參考官網(wǎng),常用配置來(lái)自于網(wǎng)絡(luò)資源,在文末有相關(guān)參考鏈接,實(shí)踐部分基于自己的項(xiàng)目進(jìn)行優(yōu)化配置。同一文件中,修改某個(gè)影響其他。 前言:本文基于weboack4.x,主要涉及webpack4 基本概念、基本配置和實(shí)際項(xiàng)目打包優(yōu)化。關(guān)于概念方面參考官網(wǎng),常用配置來(lái)自于網(wǎng)絡(luò)資源,在文末有相關(guān)參考鏈接,實(shí)踐部分基于自己的項(xiàng)目進(jìn)行...

    Scorpion 評(píng)論0 收藏0
  • 手摸帶你實(shí)現(xiàn) 小游戲<別踩白塊兒 -- 內(nèi)有游戲鏈接>

    摘要:別踩白塊兒使用白鷺引擎編寫(xiě)的游戲游戲地址準(zhǔn)備工作了解白鷺引擎并安裝編寫(xiě)工具安裝游戲引擎安裝創(chuàng)建項(xiàng)目創(chuàng)建項(xiàng)目可以選擇不同版本的引擎,創(chuàng)建成功之后還可以查看,對(duì)發(fā)布進(jìn)行設(shè)置。 別踩白塊兒 使用(白鷺引擎)Egret編寫(xiě)的游戲 showImg(https://user-gold-cdn.xitu.io/2018/10/26/166af8033a59fdbf?w=500&h=840&f=gif...

    zhoutk 評(píng)論0 收藏0
  • 摸手帶你用vue擼后臺(tái) 系列一(基礎(chǔ)篇)

    摘要:詳細(xì)具體的使用可以見(jiàn)文章手摸手,帶你優(yōu)雅的使用。為了加速線上鏡像構(gòu)建的速度,我們利用源進(jìn)行加速并且將一些常見(jiàn)的依賴打入了基礎(chǔ)鏡像,避免每次都需要重新下載。 完整項(xiàng)目地址:vue-element-admin系類文章二:手摸手,帶你用vue擼后臺(tái) 系列二(登錄權(quán)限篇)系類文章三:手摸手,帶你用vue擼后臺(tái) 系列三(實(shí)戰(zhàn)篇)系類文章四:手摸手,帶你用vue擼后臺(tái) 系列四(vueAdmin 一...

    xiaotianyi 評(píng)論0 收藏0
  • 摸手帶你用vue擼后臺(tái) 系列三(實(shí)戰(zhàn)篇)

    摘要:社區(qū)的認(rèn)可目前已經(jīng)是相關(guān)最多的開(kāi)源項(xiàng)目了,體現(xiàn)出了社區(qū)對(duì)其的認(rèn)可。監(jiān)聽(tīng)事件手動(dòng)維護(hù)列表這樣我們就簡(jiǎn)單的完成了拖拽排序。 完整項(xiàng)目地址:vue-element-admin 系類文章一:手摸手,帶你用vue擼后臺(tái) 系列一(基礎(chǔ)篇)系類文章二:手摸手,帶你用vue擼后臺(tái) 系列二(登錄權(quán)限篇)系類文章三:手摸手,帶你用vue擼后臺(tái) 系列三(實(shí)戰(zhàn)篇)系類文章四:手摸手,帶你用vue擼后臺(tái) 系列...

    Channe 評(píng)論0 收藏0
  • 摸手,帶你用vue擼后臺(tái) 系列三(實(shí)戰(zhàn)篇)

    摘要:社區(qū)的認(rèn)可目前已經(jīng)是相關(guān)最多的開(kāi)源項(xiàng)目了,體現(xiàn)出了社區(qū)對(duì)其的認(rèn)可。監(jiān)聽(tīng)事件手動(dòng)維護(hù)列表這樣我們就簡(jiǎn)單的完成了拖拽排序。 完整項(xiàng)目地址:vue-element-admin 系類文章一:手摸手,帶你用vue擼后臺(tái) 系列一(基礎(chǔ)篇)系類文章二:手摸手,帶你用vue擼后臺(tái) 系列二(登錄權(quán)限篇)系類文章三:手摸手,帶你用vue擼后臺(tái) 系列三(實(shí)戰(zhàn)篇)系類文章四:手摸手,帶你用vue擼后臺(tái) 系列...

    zgbgx 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<