全局安裝webpack
npm install webpack webpack-cli -g
全局安裝webpack會有個問題,就是當你有兩個項目依賴于不同版本的webpack,就會有一個項目打包不了,所以還是不全局安裝webpack比較好。
在當前項目安裝webpack
- 新建webpack-demo目錄,然后進行npm項目初始化
npm init 或者 npm init -y
- 在剛創(chuàng)建出來的package.json中添加
private字段
"private": true /**表示私有的**/
- 如果webpack已經(jīng)全局安裝,需要卸載
npm uninstall webpack webpack-cli -g /**卸載全局安裝的webpack**/
- 在項目根目錄下執(zhí)行安裝命令
npm install webpack webpack-cli --save-dev
- 使用npx打印出當前的webpack版本
npx webpack -v
安裝指定版本的webpack
npm info webpack /*查看webpack所有版本信息*/
npm install webpace@4.29.6 --save-dev
webpack的配置文件
在項目根目錄新建文件webpack.config.js
const path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
webpack手動打包命令
npx webpack /**默認會使用根目錄下的webpack.config.js配置文件進行打包**/
npx webpack --config webpack.config.js /**指定配置文件打包**/
使用npm scripts 簡化webpack命令
- 在package.json中的scripts字段下添加
bundle字段
"bundle": "webpack"
- 使用npm命令打包
npm run bundle
使用file-loader打包圖片
- 安裝file-loader
npm install file-loader --save-dev
- 在配置文件webpack.config.js中添加字段
module: {
rules: [
{
test: /\.(jpg|png|svg|gif)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]', /**原名字輸出**/
outputPath: 'images/', /**打包后存放圖片的文件夾**/
}
}
}
]
}
使用url-loader打包圖片
- 安裝url-loader
npm install url-loader --save-dev
- 在配置文件webpack.config.js中添加字段
module: {
rules: [
{
test: /\.(jpg|png|svg|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
limit: 204800, /**小于20kb的圖片,打包成base64放到bundle.js文件**/
}
}
}
]
}
使用style-loader和css-loader打包css文件
- 安裝style-loader 和 css-loader
npm install style-loader css-loader --save-dev
- 在webpack.config.js文件中添加配置
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
使用sass-loader打包.sass文件
- 安裝sass-loader 和 node-sass
npm install sass-loader node-sass --save-dev
- 在webpack.config.js文件中添加配置
module: {
rules: [{
test: /\.sass$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}]
}
數(shù)組形式的loader是從下到上,從右到左執(zhí)行 sass-loader -> css-loader -> style-loader
使用postcss-loader自動添加css廠商前綴
- 安裝postcss-loader
npm install postcss-loader --save-dev
- postcss-loader需要配合autoprefixer插件使用
npm install autoprefixer --save-dev
- 在項目根目錄添加postcss.config.js文件
module.exports = {
plugins: [
require('autoprefixer');
]
}
- 在webpack.config.js中添加配置
module: {
rules: [{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader']
}]
}
- 確保所有的scss文件都會被所有l(wèi)oader處理,修改webpack.config.js中的配置
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
/**確保每個scss都被所有l(wèi)oader處理**/
importLoaders: 2,
/**分模塊打包css**/
modules: true
}
},
'sass-loader',
'postcss-loader'
]
}
使用file-loader打包字體文件
- 安裝file-loader
npm install file-loader --save-dev
- 在webpack.config.js文件中添加modules
{
test: /\.(eot|ttf|svg)$/,
use: {
loader: 'file-loader'
}
}
使用插件使webpack打包更便捷
1). 安裝自動生成index.html插件 html-webpack-plugin
- 安裝html-webpack-plugin
npm install html-webpack-plugin --save-dev
htmlWebpackPlugin 會在打包結(jié)束后,自動生成index.html文件,并把對應(yīng)的js引入index.htm文件中
- 在webpack.config.js中引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html' /**自動以src/index.html為模板,在dist目錄下生成新的index.html文件**/
})
]
2)使用clean-webpacl-plugin插件自動刪除dist插件再打包
- 安裝插件clean-webpack-plugin
npm install clean-webpack-plugin --save-dev
- 在webpack.config.js中使用插件
const CleanWebpackPlugin = require('clean-webpack-plugin');
plugins: [new CleanWebpackPlugin({})] /**默認清除的是dist目錄**/
sourceMap配置
sourceMap 映射src目錄的源文件,能定位到哪行報錯
- 開啟sourceMap,在wepback.config.js中添加配置
devtool: 'source-map'
- sourceMap的最佳實現(xiàn)
devtool: 'cheap-module-eval-source-map' /**開發(fā)環(huán)境中使用**/
devtool: 'cheap-module-source-map' /**生產(chǎn)環(huán)境**/
使用WebpackDevServer提高開發(fā)效率
- 安裝webpack-dev-server
npm install webpack-dev-server --save-dev
- 在webpack.config.js中配置devServer
devServer: {
contentBase: './dist',
open: true, /**open true 可以自動打開瀏覽器**/
proxy: {
"/api": "http://new.junbang.com/" /**請求api代理轉(zhuǎn)發(fā)**/
},
port: 8081, /**端口號**/
}
- 在package.json中添加watch命令
"scripts": {
"watch": "webpack --watch",
"start": "webpack-dev-server"
}
使用:npm run watch 監(jiān)聽文件有變化自動打包
使用:npm run start 可以自動監(jiān)聽,自動打包, 自動刷新瀏覽器
自定義server
- 需要安裝express和webpack-dev-middleward這兩個插件
npm install express webpack-dev-middleware --save-dev
- 新建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, {
publicPath: config.output.publicPath
}));
app.listen(3000,() => {
console.log('server is running on prot 3000');
});
- 在package.json中設(shè)置serve命令
"scripts": {
"serve": "node server.js"
}
npm run serve 使用的就是我們server.js配置的服務(wù)器
不過server.js還需要寫很多,這只是簡單的server
模塊熱更新HMR
- 開啟模塊熱更新,在webpack.config.js中添加配置
devServer: {
hot: true,
hotOnly: true, /**hotOnly: false 瀏覽器可以自動刷新**/
}
- 使用HMR插件,在webpack.config.js中引入插件
const webpack = require('webpack');
plugins: {
new webpack.HotModuleReplacementPlugin()
}
使用npm run start重啟服務(wù)使新的配置生效
模塊熱更新HMR作用:
css編寫. 修改無需重新刷新瀏覽器就可顯示效果
js模塊發(fā)生改變可以指定更新當前js模塊,不需要刷新瀏覽器
- js模塊熱更新,在index.js文件中編寫代碼
import number from './number';
number();
if (module.hot) {
module.hot.accept('./number', () => {
/**當number模塊有改變重新渲染**/
number();
}
}
使用Babel處理ES6語法
- 安裝babel-loader 和 @babel/core
npm install --save-dev babel-loader @babel/core
- 在webpack.config.js中添加配置
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"]
}
}]
}
- 安裝@babel/preset-env模塊對ES6語法進行翻譯
npm install @babel/preset-env --save-dev
- 在webpack.config.js中的modules rules babel-loader 中配置options對象
options: {
presets: ["@babel/preset-env"]
}
/**或者在項目根目錄下創(chuàng)建配置文件.bablerc**/
{
"presets": ["@babel/preset-env"]
}
- 使用@babel/polyfill 加上低版本沒有的語法, 比如map() . Promise等
npm install --save @babel/polyfill
- 在所以代碼運行之前,可以放在入口文件index.js最頂部
import "@babel/polyfill";
- polyfill默認會把所有翻譯過代碼都加進來,有時候我們沒有用到的新方法,也有了翻譯的方法在里面了,所以我們要過濾掉,沒用上的就不要加載進來了,這樣包更小,所以在webpack.config.js babel-loader中修改配置
options: [['@babel/preset-env', {
useBuiltIns: 'usage'
}]]
- 已經(jīng)支持ES6語法的瀏覽器版本,沒必要在翻譯所以我們可以指定瀏覽器版本
options: [['@babel/preset-env', {
targets: {
chrome: "67" /**更多瀏覽器版本配置去babel官網(wǎng)查看**/
},
useBuiltIns: 'usage'
}]]
- 當指定了useBuiltIns: 'usage',會自動引入@babel/polyfill,所以可以去掉index.js import的@babel/polyfill,但是可以需要安裝依賴
npm install --save core-js
如果是寫業(yè)務(wù)代碼以上配置沒問題,如果要寫框架. 類庫. 第三方模塊什么的,為了避免變量的全局污染(因為polyfille翻譯的變量掛載到全局變量)而使用plugin-transform-runtime插件
安裝transform-runtime插件
npm install --save-dev @babel/plugin-transform-runtime
npm install --save #babel/runtime
- 在webpack.config.js中修改配置
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
plugins: [["@babel/plugin-transform-runtime", {
corejs: 2
helpers: true,
regenerator: true
useESModules: false
}]]
}
}]
}
- 因為我們配置了corejs: 2,所以要加裝corejs的依賴
npm install --save @babel/runtime-corejs2
配置React代碼的打包
babel也可以打包react代碼
- 安裝react框架
npm install react react-dom --save
- 安裝@babel/preset-react
npm install --save-dev @babel/preset-react
- 在.babelrc中添加配置
presets: ["@babel/preset-env","@babel/preset-react"]
使用Tree Shaking去掉沒有引用的方法/ 模塊
Tree Shaking只支持 ES Module 就是import export不支持require('')
- 在mode: 'development'中配置Tree Shaking, 在webpack.config.js中
optimization: {
usedExports: true
}
在mode: 'production'中 默認就有,不需要添加任何配置
在package.json中配置不需要Tree Shaking的模塊
"sideEffects": false /**所有模塊都需要Tree Shaking**/
"sideEffects": ['@babel/polly-fill', '*.css'] /**對這兩個模塊不做Tree Shaking**/
Development 和 Production 模式的區(qū)分打包
創(chuàng)建webpack.common.js 放公有的配置項
創(chuàng)建webpack.dev.js 放開發(fā)獨有的配置項
創(chuàng)建webpack.prod.js 放生產(chǎn)獨有的配置項
使用webpack-merge 把webpack.common.js合并到其他兩個文件
npm install webpack-merge --save-dev
- 在webpack.dev.js中引入插件
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const devConfig = {
...
}
module.exports = merge(commonConfig, devConfig);
在webpack.prod.js中也作跟webpack.dev.js同樣的處理
Code Splitting 代碼分割
- 同步加載模塊 在webpack.config.js中配置splitChunks
optimization: {
splitChunks: {
chunks: 'all'
}
}
異步加載模塊無需任何配置默認就會自動分割
創(chuàng)建一個異步加載的js模塊
/** webpackChunkName: "lodash" 給這個模塊起這個文件名 **/
function getComponent() {
return import(/* webpackChunkName: "lodash"*/ 'lodash').then(({default: _}) => {
var element = document.createElement('div');
element.innerHtml = _.join(['@', 'bang']);
return element
});
}
getComponent().then(element => {
document.body.appendChild(element);
});
- 安裝babel-plugin-dynamic-import-webpack對異步加載模塊語法進行翻譯
npm install @babel/plugin-syntax-dynamic-import --save-dev
- 在.babelrc配置文件中使用plugin-syntax-dynamic-import插件
plugins: ["@babel/plugin-syntax-dynamic-import"]
SplitChunksPlugin配置參數(shù)詳解
/** 在webpack.config.js文件中 **/
optimization: {
splitChunks: {
/** all:-- 所有模塊都分割 **/
/** async -- 只對異步加載的模塊進行分割 **/
/** initial -- 只對同步模塊進行分割 **/
chunks: 'all',
minSize: 30000, /** 大于30000b(30kb)才會分割 **/
maxSize: 0, /** 一般不配置,會對大文件再次分割 **/
minChunks: 1, /** 引用這個模塊超過一次就會分割 **/
maxAsyncRequests: 5, /** 同時只能加載分割5個庫 **/
maxInitialRequests: 3, /** 最多分割出3個文件 **/
automaticNameDelimiter: "~", /** 文件名連接符 **/
name: true
cacheGroups: {
/** 同步模塊加載必需配置
vendors: {
test: /[\\/]node_modules[\\/]/,
/** 如果模塊同時滿足cacheGroups和default, **/
/** 根據(jù)priority來決定模塊的歸屬誰的值大屬于誰 **/
priority: -10,
filename: 'vendors.js' /** 打包成的文件名 **/
},
/** 同步非node_modules里面的模塊配置專用 **/
default: {
priority: -10,
/** 已經(jīng)打包過的模塊忽略 **/
/** 不再打包分割 **/
reuseExistingChunk: true,
filename: 'common.js'
}
}
}
}
lazy loading 懶加載異步模塊
- 打包分析工具
首先在打包的時候生成josn格式的描述文件,然后在package.json中添加命令
scripts: {
"dev-build": "webpack --profile --json > stats.json --config webpack.dev.js"
}
使用:npm run dev-build
生成的.stats.json文件可以用來分析
使用Preloading, 空閑時候,靜默加載我們的異步模塊
- 查看js文件中代碼的使用率,打開控制臺 command + shift + p
- 搜索 Coverage 選中show Coverage 然后點擊錄制按鈕變紅后刷新頁面
- 在index.js中創(chuàng)建一個異步加載模塊js的方法
document.addEventListener('click', () => {
import(/* webpackPrefetch: true */ './click.js').then(({default: func}) => {
func();
});
});
正常情況下呢,我們只有在點擊的時候,才加載click.js,但是配置了Prefetch: true,就會空閑時主動加載我們的click.js。空閑時主動加載解決了異步加載慢的問題,因為文件加載過了,再點擊加載就會使用緩存的文件。
css文件代碼分割
- webpack 用style-loader處理的css會放到文件<head>標簽中
- 使用mini-css-extract-plugin把css分割成單獨文件
npm install --save-dev mini-css-extract-plugin
- 這個插件不支持熱更新(截止目前),所以一般是生產(chǎn)環(huán)境才用
- 在webpack.prod.js中 將style-loader替換為MiniCssExtractPlugin.loader
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new MiniCssExtractPlugin({});
]
module: {
rules: [
{
test: /\.css$/,
use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' ]
]
}
- 過濾Tree Shakking, 在package.json中添加配置
"sideEffects": ["*.css"]
- 配置filename和chunkFilename, 在webpack.prod.js中
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[name].chunk.css'
});
}
- 使用optimize-css-assets-webpack-plugin對css合并和壓縮
npm install --save-dev optimize-css-assets-webpack-plugin
- 在webpack.prod.js中使用optimize-css-assets-webpack-plugin
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
optimization: {
minimizer: [new OptimizeCssAssetsPlugin({})]
}
多個入口文件引用的css打包到一個css文件
- 借助splitChunks, 在webpack.prod.js中添加配置
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true
}
}
}
}
- 還可以把一個入口文件引入的所有css打包到對應(yīng)的一個文件。這樣每個入口引用的css,就會生成對應(yīng)一個css文件。這個配置也借助splitChunks,在webpack.prod.js中配置
optimization: {
splitChunks: {
cacheGroups: {
mainStyles: {
name: 'main',
test: (m,c,entry = 'main') => m.constructor.name === 'CssModule && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true
}
}
}
}
webpack與瀏覽器緩存
- 在webpack.prod.js中配置contenthash
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].js'
}
contenthash在文件沒有改變時,它不會變,對應(yīng)的文件有改變它的值就會變,這樣瀏覽器加載的就是新文件
通過webpack.ProvidePlugin插件自動幫我們引用沒有import的模塊
- 在webpack.common.js中配置ProvidePlugin
const webpack = request('webpack');
plugins: [
new webpack.ProvidePlugin({
$: 'jquery'
})
]
解決問題: 有的模塊使用的是jquery,但是沒有import jquery,$對象找不到,只在首頁引入jquery是不行的,這時候借助webpack.ProvidePlugin,幫我們在使用$對象的模塊引入jquery。
讓this都指向window
- 安裝
imports-loader
npm install imports-loader --save-dev
- 在webpack.common.js中添加配置
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
}, {
loader: 'imports-loader?this=>window'
}]
}]
}
環(huán)境變量的使用
- 在webpack.common.js中使用Env
comst merge = require('webpack-merge');
const prodConfig = require('./webpack.prod.js);
const devConfig = require('./webpack.dev.js');
module.exports = (env) => {
if (env && env.production) {
return merge(commonConfig, prodConfig);
} else {
return merge(commonConfig, devConfig);
}
}
- 在package.json中修改命令
"scripts": {
"dev-build": "webpack -- config ./webpack.common.js",
"build": "webpack --env.production --config ./webpack.common.js"
}
Library的打包
- 創(chuàng)建一個自己的包模塊library
npm init -y
- 在包目錄下新文件src/math.js 和 src/string.js
- 在src/math.js中編寫代碼
export function add(a, b) {
return a + b;
}
export function minus(a, b) {
return a - b;
}
export function multiply(a, b) {
return a * b;
}
export function division(a, b) {
return a / b;
}
- 在src/string.js中編寫代碼
export function join(a, b) {
return a + " " + b;
}
- 在src/index.js中編寫代碼
import * as math from './math.js';
import * as string from './string';
export default { math, string }
- 在項目中安裝webpack 和 webpack-cli
npm install webpack webpack-cli --save
- 在項目中創(chuàng)建webpack.config.js
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js'
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'library.js',
library: 'library',
libraryTarget: 'umd'
}
}
- 在package.js中配置入口文件和打包命令
main: './src/index.js',
scripts: {
"build": "webpack"
}
別人使用我們的庫可能用到的引入方式
1、import library from 'library';
2、const library = require('library');
3、require(['library'], function() {});
4、<script src="./library.js"></script>通過在webpack.config.js中配置
libraryTarget: 'umd'可以使用前面三種引用通過在webpack.config.js中配置
library: 'library'可以使用<script>引用在自己的庫中使用別人的庫,這里引入lodash庫
npm install lodash --save
- 在src/string.js中 使用lodash
import _ from 'lodash';
export function join(a, b) {
return _.join([a, b], ' ');
}
- 問題:默認的lodash也會被打包到我們的代碼中,而別人不知道,也有可能在自己項目中,引入了自己的lodash,造成模塊冗余,所以需要在webpack.config.
externals: ['lodash']
注意:這個時候別人用我們的庫需要手動引入lodash再引入library(我們的庫)
- 讓別人方便的使用我們的代碼,可以在package.json中配置
"main": "./dist/library.js",
- 在npm官網(wǎng)注冊一個賬號,并把我們的庫上傳到npm
npm adduser -- 回車添加賬號和密碼
npm publish -- 把包上傳到npm倉庫
- 安裝我們的庫
npm install library
- 我們自己創(chuàng)建的庫名跟npm上的庫名不能相同,不然有可能上傳不了。
PWA的打包配置
PWA作用是緩存頁面,當服務(wù)器掛掉了,還是可以看到原來緩存的頁面
- 安裝workbox-webpack-plugin插件
npm install workbox-webpack-plugin --save-dev
- 在webpack.prod.js中使用workbox-webpack-plugin插件
const WorkboxPlugin = require('workbox-webpack-plugin');
plugins: [
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true
})
]
- 在index.js中看看瀏覽器是否支持PWA,并注冊我們要緩存的文件
if('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js)
.then(registration => {
console.log('service-worker registed');
}).catch(error => {
console.log('service-worker register error');
});
}
}
這樣注冊了service-worker.js之后,本來我們需要npm run dev 把服務(wù)開啟之后能訪問,如果關(guān)掉服務(wù)再刷新,因為已經(jīng)訪問成功過一次,有了緩存,所以還是可以看到頁面
webpack打包TypeScript
- 安裝ts-loader 和 typescript
npm install ts-loader typescript --save-dev
- 在webpack.config.js中添加配置
const path = require('path');
module.exports = {
entry: './srcindex.tsx',
module: {
rules: [{
test: /\.[tsx]|[ts]?$/,
use: 'ts-loader',
exclude: /node_modules/
}]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
- 在項目根目錄創(chuàng)建tsconfig.json(必需)
{
"compilerOptions": {
"outDir": "./dist",
"module": "es6",
"target": "es5",
"allowJs": true,
}
}
注意:TypeScript 不能對引用的外部模塊校驗,比如調(diào)用lodash中的join()方法,不傳參數(shù)也不報錯。如需要提示,需安裝@types/lodash,這樣不傳參數(shù)也會有提示哦。 更多庫的@type檢測請上網(wǎng)搜索!
- 安裝@types/lodash
npm install @types/lodash --save-dev
webpackDevServer實現(xiàn)請求轉(zhuǎn)發(fā)
- 在webpack.config.js中配置proxy
devServer: {
proxy: {
'/api': 'http://new.junbang.vip'
}
}
- 更復(fù)雜的配置 比如把請求header.json 變成demo.json
devServer: {
proxy: {
'/api': {
treget: 'http://new.junbang.vip',
pathRewrite: {
'header.json': 'demo.json'
}
}
}
}
- 如果后臺對origin做了限制可以加配置
changeOrigin: true /**建議始終都加**/
WebpackDevServer解決單頁面應(yīng)用路由問題
- 在webpack.config.js中
devServver: {
historyApiFallback: {
rewrites: [{
from: /\.*/,
to: 'index.html'
}]
}
}
上面的配置等價于historyApiFallback: true,這個配置只在開發(fā)有用,上線需要對線上服務(wù)器也配置。配置好了,訪問不了的頁面就會顯示首頁
Eslint 在wepback中的配置
- Eslint是什么?Eslint是約束代碼的規(guī)范
- 安裝Eslint
npm install eslint --save-dev
- 生成配置文件
npx eslint --init
在根目錄發(fā)現(xiàn)文件.eslintrc.
- 使用babel-eslint
npm install babel-eslint --save-dev
- 在.eslintrc.js中配置
"parser": "babel-eslint"
- 使用命令校驗src目錄下的js
npx eslint src
- 忽略規(guī)則,在.eslintrc.js中
"rules": {
"react/jsx-filename-extension": 0
}
把規(guī)則置成0就可以忽略 1是警告 2是報錯
在webpack使用eslint-loader校驗代碼
- 安裝eslint-loader
npm install eslint-loader --save-dev
- 在webpack.config.js中添加配置
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader']
}]
}
- 想要在
npm run serve的時候把eslint校驗的錯誤在瀏覽器上輸出, 可以在webpack.config.js中配置
devServer: {
overlay: true
}
注意:在webpack中使用eslint-loader檢測代碼會影響打包速度??梢栽趃it 生命鉤子,提交代碼前校驗代碼,不符合不給提交
webpack性能優(yōu)化
1.提升webpack打包速度
1)跟上技術(shù)的迭代,使用最新版node/npm/yarn/webpack
2)盡量少用loader,loader也應(yīng)該檢測盡量少的代碼
3)比如校驗js文件的時候,忽略/node_modules/
4)或者只對src下面的文件校驗
include: path.resolve(__dirname, './src')
5)合理使用插件,使用性能好的,官方推薦的2.合理配置resolve參數(shù)
test: /\.jsx?$/'?' 表示'x'可有可無 => js/jsx
然后在webpack.config.js中添加配置resolve: { extensions: ['.js', '.jsx'] }表示我們加載import 的時候,不寫文件后綴名,默認會找.js/.jsx
3.當我們import 一個文件夾,可能指定要找的文件名
resolve: { mainFiles: ['index', 'main'] }4.使用第三方模塊時候,因為我們不會去改動這些模塊,但是每次打包都會重新分析一次這些第三方模塊,浪費時間,所以希望只在第一次分析,后面直接用就行。所以
1)新建webpack.dll.js文件
const path = require('path'); module.exports = { mode: 'production', entry: { vendors: ['react', 'react-dom', 'lodash'] }, output: { filename: '[name].dll.js', path: path.resolve(__dirname, '../dll'), library: ['name'] /** library 可以把當前模塊暴露出去 **/ } }
- 把這些第三方模塊引入index.html中,可以手動引入,也可以用插件
npm install add-assets-html-webpack-plugin --save-dev
- 在webpack.config.js中使用插件
const AddAssetHtmlWebpackPlugin require('add-asset-html-webpack-plugin'); new AddAssetHtmlWebpackPlugin({ filepath: path.resolve(__dirname, '../dll/vendors.dll.js') })
- 在寫代碼使用到第三方模塊時,使用vendors.dll.js
npm install dll-plugin --save-dev
- 在webpack.config.js中配置
const webpack = require('webpack'); plugins: [ new webpack.DllPlugn({ name: '[name]', path: path.resolve(__dirname, '../dll/[name].manifest.json') }), new webpack.DllReferencePlugin({ manifest: path.resolve(__dirname, '../dll/vendors.manifest.json') }) ]配置完成,第三方模塊我們只需要手動打包一次,后面在打包項目的時候,就只會打包我們改動代碼的目錄src
多頁面打包配置
- 首先需要配置多個入口,生成多個js文件
entry: {
main: './src/index.js',
list: './src/list.js'
}
- 其次多new 幾個HtmlWebpackPlugin,生成那就的html文件
new HtmlWebpackPlugin({
template: 'src/index.html',
filename: 'index.html',
chunks: ['runtime', 'vendors', 'main']
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
filename: 'list.html',
chunks: ['runtime', 'vendors', 'list']
})
- 可能遍歷configs.entry自動生成