什麼是webpack
webpack 是一個現代 JavaScript 應用程式的靜態模組打包器(module bundler)。當 webpack 處理應用程式時,它會遞迴地構建一個依賴關係圖(dependency graph),其中包含應用程式需要的每個模組,然後將所有這些模組打包成一個或多個 bundle
可以做的事情
程式碼轉換、檔案優化、程式碼分割、模組合併、自動重新整理、程式碼校驗、自動釋出
複製程式碼
需要提前掌握的內容
- 需要node基礎,以及npm的使用
- 掌握es6語法
主要學習webpack哪些內容
- webpack常見配置
- webpack高階配置
- webpack優化策略
- ast抽象語法樹
- webpack中的Tapable
- 掌握webpack流程,手寫webpack
- 手寫webpack中常見的loader
- 手寫webpack中常見的plugin
建立檔案
mkdir webpack-test && cd webpack-test
mkdir src
touch src/index.js
複製程式碼
初始化檔案
npm init -y 初始檔案(預設的)
npm init
複製程式碼
開始打包
npx webpack
複製程式碼
配置webpack.config.js
touch webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devServer: { // 開發伺服器的配置
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 3000
},
mode: 'development', // 模式 預設兩種production development
entry: './src/index.js', //入口
output: {
filename: 'bundle.js', //打包後的檔名
path: path.resolve(__dirname, 'dist'), //路徑必須是一個絕對路徑
},
plugins: [// 陣列放著所有的webpack外掛
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
})
]
}
複製程式碼
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
複製程式碼
index.js
var root = document.getElementById("root");
root.innerHTML="你好"
複製程式碼
webpack常見配置
npm i webpack webpack-cli -D
npm i html-webpack-plugin -D
複製程式碼
使用模板 html
- html-webpack-plugin 可以指定template模板檔案,將會在output目錄下,生成html檔案,並引入打包後的js.
npm i html-webpack-plugin -D
複製程式碼
webpack-dev-server
- webpack-dev-server提供了一個簡單的Web伺服器和實時熱更新的能力
npm i webpack-dev-server -D
複製程式碼
pagkage.js
{
"name": "webpack-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.30.0",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.3.1"
}
}
複製程式碼
目前的目錄
啟動專案
npm run dev
複製程式碼
瀏覽器輸入http://localhost:3000/
載入樣式檔案
- 在src目錄下建立一個index.css
body{
background-color:red;
}
複製程式碼
- 在index.js中引入index.css
require('./index.css');
複製程式碼
- webpack.config.js增加一些引數
module: { //模組
rules: [ // 規則 css-loader
// style-loader 把css插入到head的標籤中
// loader的特點: 希望單一
// loader的用法: 字串只用一個loader
// 多個loader需要[]
// loader的順序 預設是從右向左執行
// loader還可以寫出物件方式
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
]
}
複製程式碼
- css-loader style-loader
npm i css-loader style-loader -D
複製程式碼
- 效果如下
載入less(sass,stylus類似)
- 在src目錄下建立一個index.less
body{
#root{
border:1px yellow solid;
color: #000;
}
}
複製程式碼
- 在index.js中引入index.less
require('./index.css');
複製程式碼
- webpack.config.js增加一些引數
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
},
'css-loader','less-loader'
]
},
複製程式碼
- less-loader
npm i less less-loader -D
複製程式碼
- 效果如下
提取單獨打包css檔案
npm i mini-css-extract-plugin -D
複製程式碼
- webpack.config.js增加一些引數
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new MiniCssExtractPlugin({
filename: 'main.css'
})
],
module: { //模組
use: [
MiniCssExtractPlugin.loader,
]
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
]
}
]
}
複製程式碼
css3樣式自動加字首
npm i postcss-loader autoprefixer -D
複製程式碼
- 在webpack-test建立postcss.config.js
module.exports = {
plugins: [require('autoprefixer')]
}
複製程式碼
- webpack.config.js增加一些引數
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
// options: {
// insertAt: 'top' //內聯樣式最高階
// }
},
'css-loader',
'postcss-loader'
]
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
},
'css-loader',
'postcss-loader',
'less-loader'
]
}
複製程式碼
轉化es6語法
npm i babel-loader @babel/core @babel/preset-env -D
npm i @babel/plugin-proposal-class-properties -D
複製程式碼
- webpack.config.js增加一些引數
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: { // 用babel-loader 需要把es6-es5
presets: [
'@babel/preset-env'
],
plugins: [
'@babel/plugin-proposal-class-properties'
]
}
}
]
複製程式碼
全域性變數引入
npm i jquery -D
npm i expose-loader -D
複製程式碼
第一種
- import $ from 'jquery';
- webpack.config.js增加一些引數
rules: [
{
test: require.resolve('jquery'),
use: 'expose-loader?$'
},
]
複製程式碼
第二種
- webpack.config.js增加一些引數
const webpack = require('webpack');
plugins: [ // 陣列放著所有的webpack外掛
new webpack.ProvidePlugin({
$: 'jquery' // 在每個模組中注入$物件
})
],
複製程式碼
引入圖片處理
// 1.在js中建立圖片來引入
// 2.在css引入backgroud('url')
// 3.<img src="" alt="" />>
npm i file-loader -D
npm i html-withimg-loader -D
複製程式碼
- webpack.config.js增加一些引數
rules: [
{
test: /\.html$/,
use: 'html-withimg-loader'
},
{
test: /\.(png|jpg|gif)$/,
use: 'file-loader'
},
]
複製程式碼
- 限制圖片大小
npm i url-loader -D
複製程式碼
- webpack.config.js增加一些引數
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 200*1024
}
}
複製程式碼
images和css打包分類
- webpack.config.js增加一些引數
plugins: [ // 陣列放著所有的webpack外掛
new MiniCssExtractPlugin({
filename: 'css/main.css'
}),
],
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 1,
outputPath: '/img/',
publicPath: 'https://www.baidu.com' // 在圖片上加域名
}
}
複製程式碼
多頁面打包
- 在scr建立一個other.js
console.log("other 一路走好!")
複製程式碼
- webpack.config.js增加一些引數
// 多入口
entry: {
index: './src/index.js',
home: './src/other.js',
},
output: {
filename: '[name].js', //打包後的檔名
path: path.resolve(__dirname, 'dist'), //路徑必須是一個絕對路徑
// publicPath: 'https://www.baidu.com'
},
plugins: [ // 陣列放著所有的webpack外掛
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
chunks: ['index']
}),
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'home.html',
chunks: ['home']
}),
]
複製程式碼
配置source-map除錯程式碼
- webpack.config.js增加一些引數
output: {
filename: '[name].js', //打包後的檔名
path: path.resolve(__dirname, 'dist'), //路徑必須是一個絕對路徑
// publicPath: 'https://www.baidu.com'
},
// devtool: 'source-map', // 1.增加對映檔案 可以幫我們除錯原始碼
// devtool: 'eval-source-map', // 2.不會產生單獨的檔案,但是可以顯示行和列
// devtool: 'cheap-module-source-map', // 3.不會產生列,但是是一個單獨的對映檔案(產生後你可以保留起來)
devtool: 'cheap-module-eval-source-map',// 4.不會長生檔案,整合在打包後的檔案中不會產生列
複製程式碼
watch實時打包
- webpack.config.js增加一些引數
entry: {
index: './src/index.js',
home: './src/other.js',
},
watch: true,
watchOptions: { // 監控的選項
poll: 1000, // 每秒問我1000次
aggregateTimeout: 500, // 防抖
ignored: /node_modules/ // 不需要進行監控哪個檔案
},
複製程式碼
常用的小外掛
- 清除dist (clean-webpack-plugin)
- 拷貝檔案(copy-webpack-plugin)
- 版權註釋(bannerPlugin)
npm i clean-webpack-plugin -D
npm i copy-webpack-plugin -D
複製程式碼
- 在webpack-test建立doc檔案,裡面建立hello.txt
- webpack.config.js增加一些引數
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
plugins: [
new CleanWebpackPlugin(),
new CopyWebpackPlugin([
{from: 'doc', to: './'}
]),
new webpack.BannerPlugin('cl by 2019')
],
複製程式碼