什麼是loader?
webpack只能打包js模塊,其他模塊的打包需要藉助loader。loader可以處理各種各樣文件類型。
- file-loader:將文件處理後移動到打包文件中
- url-loader:可以實現file-loader的功能,而且可以限制文件限制,在文件比較小的情況下,可以返回一個DataURL,也可以打包字體。file-loader和url-loader,優先使用url-loader
{
test: /\.(png|jpe?g|gif)$/i,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images',
limit: 10240 // 小文件會打包成base64放到文件中,減少文件請求
}
}
}
- style-loader,css-loader,postcss-loader:打包css文件
- style-loader:將樣式掛在在head裏
- css-loader:生成css內容
- postcss-loader:css3新特性加廠商前綴
{
test: /\.scss$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
// modules:true, // css模塊化,兩個文件的樣式不會耦合,使樣式獨立
importLoaders: 2 // 在該loader之前用2個loader處理import的資源
}
},
'sass-loader', // 翻譯scss文件
'postcss-loader',
]
}
什麼是plugins
plugins插件是 webpack 的支柱功能,可以解決 loader 無法實現的其他事。
- html-webpack-plugin:會在打包結束後,自動生成一個html文件,並把打包生成的js文件自動引入到這個html中,打包之後運行
- clean-webpack-plugin:打包之前運行,默認移除webpack的output中的所有文件
- 使用方法
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
CleanWebpackPlugin
} = require('clean-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({ // 自動生成html文件
template: 'src/index.html'
}),
new CleanWebpackPlugin(), // 清空上次打包文件
],
}
source-map的配置
SourceMap是映射關係,可以知道打包出的文件報錯位置映射到源文件中的哪個文件的具體位置,開發環境與實際代碼不一致時可以幫助我們debug到原始代碼。
- development環境可以配置爲
devtool: 'cheap-module-eval-source-map', // 開發環境配置
- production環境可以配置爲
devtool: 'cheap-module-source-map', // 生產環境配置
- 配置介紹
- eval:使用eval包裹模塊代碼,然後在末尾添加模塊來源 //# sourceURL,依靠sourceURL找到原始代碼的位置。包含eval關鍵字的配置項不產生.map文件(eval依靠sourceURL定位原始代碼,其他都是.map定位)—性能最好
- source-map:產生.map文件 — 性能最低
- cheap:不包含原始代碼的列信息,也就是說當你在瀏覽器中點擊該代碼的位置,光標只定位到行數,而不包含具體字符位置。也不包含loaders的sourcemap,如果你使用了babel等代碼編譯工具,定位到的代碼將是經過編譯的代碼位置,而不是原始代碼
- module:包含loader的sourcemap
- inline:將.map經過base64編碼作爲DataURI嵌入,不單獨生成.map文件
WebppackDevServer和Hot Module Replacement(HMR)
WebppackDevServer:用在開發環境,提升開發效率;HRM:開發過程中,無需重新加載整個頁面,去更新各種模塊。
- 配置WebppackDevServer
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true, // 開啓HMR的功能
hotOnly:true // HMR不生效時,瀏覽器不自動刷新
},
- 引入插件
const webpack = require('webpack');
plugins: [
new webpack.HotModuleReplacementPlugin()
]
- 使用
在入口文件中加入以下代碼:如果當前項目開啓了HMR的功能,支持Hot module reload,js需要寫這段代碼才能實現熱更新。css不需要寫,是因爲css-loader底層已經實現了熱更新。vue-loader也內置了這部分。但是如果在項目中引入了一些比較偏的數據類文件,還是要寫這部分代碼。
if(module.hot) {
module.hot.accept('./number',() => {
document.body.removeChild(document.getElementById('number'));
number();
})
}
使用babel處理es6語法
- 安裝
npm install --save-dev babel-loader @babel/core
- 在webpack.config.js中使用
babel-loader是webpack與babel通信的橋樑,並不會翻譯es6語法,還需要藉助其他模塊,@babel/preset-env包含了所有es6轉換成es5的翻譯規則語法轉換
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
}
- 安裝preset-env
npm install @babel/preset-env --save-dev
- 使用
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
['@babel/preset-env', {
targets: {
chrome: '76'
},
useBuiltIns: 'usage' // 當做babel-polyfill填充時,根據業務代碼決定加哪些翻譯代碼
}]
]
}
}
- 引入babel-polyfill
將babel-presets缺失的變量和函數補充到低版本瀏覽器中。如果放到業務代碼最頂部的入口文件中,打包時會將不需要的文件打到文件中,導致打包文件大小變大,所以配置useBuiltIns可以做到按需引入polyfill的內容。
import "@babel/polyfill";
以上方式引入polyfill會污染全局環境。如果是寫一些UI組件或者類庫,不能用這種引入方法。可以用下面這種方式配置:
- 安裝@babel/plugin-transform-runtime
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
- 使用
'plugins': [
['@babel/plugin-transform-runtime', {
'corejs': 2, // npm install --save @babel/runtime-corejs2
'helpers': true,
'regenerator': true,
'useESModules': false
}]
]
以上是最近學習webpack的一些成果,如果有不對的,歡迎大家指正哦~