webpack.config.js基礎配置
webpack 有4大概念
- 入口(entry)
- 輸出(output)
- loader
- 插件(plugins)
- 入口與出口
//webpack.config.js
const path = require('path')
module.exports = {
mode:'development', // 指定生產還是開發
entry:'./src/index.js', // 入口文件
output:{
filename:'bundle.js', // 打包後的文件名
path:path.resolve(__dirname,'./dist') // 這裏需指定一個絕對路徑 我們需要node的path模塊去解析路徑
}
}
mode: 指定環境是development還是production 決定了打包出來的文件是壓縮還是未壓縮的
entry: 入口起點(entry point)指示 webpack 應該使用哪個模塊,來作爲構建其內部依賴圖的開始。進入入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。 其中分爲單入口跟多入口配置 可以是string,array,object
// entry:'./src/index.js' 是下面的簡寫
entry:{
main: './src/index.js'
},
output:包含打包後的名字跟路徑, 如果是多入口應用, 可以設置filename爲[name].js, entry裏的key值會替換掉name 生成文件夾。
- loader
loader 用於對模塊的源代碼進行轉換。
const path = require('path')
module.exports = {
mode:'development', // 指定生產還是開發
entry:'./src/index.js', // 入口文件
output:{
filename:'bundle.js', // 打包後的文件名
path:path.resolve(__dirname,'./dist') // 這裏需指定一個絕對路徑 我們需要node的path模塊去解析路徑
},
module: {
rules: [] // 包含一系列的規則
}
}
- plugin
plugin是一個具有 apply 屬性的 JavaScript 對象。apply 屬性會被 webpack compiler 調用,並且 compiler 對象可在整個編譯生命週期訪問。
// 代碼省略
module: {
rules: [ ] //包含一系列規則
},
plugins: [
// new PluginName 去生成js對象供給 webpack compiler 調用
]
- 本地開發配置服務
yarn add webpack-dev-server -D
本地開發需要安裝webpack-dev-server 內部是基於express 實現的一個服務 ,可讓讓服務運行在本地,開發更方便
安裝完畢在dist目錄下新建一個index.html 並且引入打包好後的bundle.js
運行npx webpack-dev-server
並未顯示index.html 需要在webpack-config.js 配置
plugins: [
// new PluginName 去生成js對象供給 webpack compiler 調用
],
devServer:{
contentBase: './dist', //當前服務以哪個作爲靜態資源路徑
host:'localhost', // 主機名 默認是localhost
port:3000, // 端口配置
open:true, // 是否自動打開網頁
}
重新運行npx webpack-dev-server
自動打開網頁並且能正常顯示頁面
如果覺得npx 麻煩的話,可以在package.json 配置腳本
"scripts": {
"dev": "webpack-dev-server --config webpack.config.js"
}
樣式文件的處理
注意:爲了顯示效果,不用每次手動修改html 我們先裝一個html模板插件
yarn add html-webpack-plugin -D
webpack-config.js 配置
const HtmlWebpackPlugin = require('html-webpack-plugin')
//....
plugins: [
// new PluginName 去生成js對象供給 webpack compiler 調用
new HtmlWebpackPlugin({
template:'./index.html', // 作爲模板的文件
filename:'index.html' //打包生成後的文件
})
],
進入正題:
樣式文件分爲css,less scss 之類的 需要各種loader 先以css作爲 樣例
需要先安裝 style-loader跟css-loader
- css的處理
yarn add style-loader css-loader -D
webpack.config.js 配置
// 代碼省略
module: {
rules: [
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
},
rules 裏放的是一個個規則對象, test是匹配到的文件 loader是從下往上執行, 從右往左執行, 也就是說命中css結尾的文件後 先用css-loader去解析,解析完畢後交由style-loader 插入到html模板裏
此處use內部 有2種寫法
-
loader:['style-loader','css-loader']
// 字符串寫法 -
loader:['style-loader',{loader:'css-loader',options:{}}
對象寫法 在options裏可以配置你需求的參數
- less的處理
需要安裝less less-loader
yarn add less less-loader -D
//webpack-config.js
module: {
rules: [
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
}
]
},
sass 配置同理
- 給樣式加前綴 如-webkit- 需要安裝autoprefixer, postcss-loader
yarn add postcss-loader autoprefixer -D
根目錄需要新建postcss.config.js
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
webpack-config.js
rules: [
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader"
]
}
]
- 提取樣式文件
yarn add mini-css-extract-plugin -D
//config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 注意MiniCssExtractPlugin 不能在development環境中使用 !!
//....
mode:'production', // 指定生產還是開發
module: {
rules: [
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"less-loader"
]
}
]
},
plugins: [
// new PluginName 去生成js對象供給 webpack compiler 調用
new HtmlWebpackPlugin({
template:'./index.html',
filename:'index.html'
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
]
//...
- 壓縮提取出來的樣式文件
需要用到uglifyjs-webpack-plugin,optimize-css-assets-webpack-plugin
yarn add optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D
//webpack-config.js
module.exports = {
//...
optimization: { // 優化項 這裏OptimizeCSSAssetsPlugin 需要UglifyJsPlugin
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({})
]
},
}
js文件的處理
這裏自然輪到我們的babel出場啦 把es6解析爲es5 需要這幾個loader
yarn add babel-loader @babel/core @babel/preset-env -D
{
test:/\.js/,
use:{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env'
]
}
}
},
es7的語法類似
class Parent{
}
這種需要@babel/plugin-proposal-class-properties
yarn add @babel/plugin-proposal-class-properties -D
另外裝飾器方面需要
yarn add @babel/plugin-proposal-decorators -D
{
test:/\.js/,
use:{
loader:'babel-loader',
options:{
presets:[
'@babel/preset-env'
],
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }]
]
}
}
},
像一些js內置的api 比如生成器 這種需要
yarn add @babel/plugin-transform-runtime -D
exclude:/node_modules // 必須配置 不然會解析到node_modules 裏的js
//....
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }]
["@babel/plugin-transform-runtime"]
]
還有一些es7 實例上的某些方法 。字符串的include 這些也要轉換
yarn add @babel/polyfill -D
需要添加到entry上或者在入口文件導入
全局變量的引入問題
有時候我們不想在每個模塊都導入某個庫或者插件 只需要這樣配置
plugins: [
// new PluginName 去生成js對象供給 webpack compiler 調用
new webpack.Provide({ // 自動在每個模塊內先導入了React
React:'react'
}),
],
靜態資源的處理
yarn add file-loader url-loader -D
{
test: /\.png|jpg|gif$/,
use: {
loader:'url-loader',
options:{
limit:2048 // 小於2k 的會用url-loader轉爲base64 否則file-loader轉爲真實img
outputPath:'static/image/' //指定輸出目錄
},
}
},
預告: 多頁面配置 跨域 區分不同環境 映射