入口、出口配置
實(shí)現(xiàn)Webpack的打包最基本的就是配置好入口、出口,npm install webpack后在根目錄創(chuàng)建webpack.config.js,代碼如下:
const path = require('path');
module.exports = {
entry: { // 也可以直接寫(xiě)成entry: './src/index.js',默認(rèn)入口就是main別名的index.js文件
main: './src/index.js' // 指把index.js設(shè)為入口文件并且設(shè)置別名為main
},
output: {
publicPath: '/', // 也可以不指定,默認(rèn)為根目錄
filename: '[name].js', // 這里[name]為占位符,即為變量,這里指復(fù)用入口文件的名字main
path: path.resolve(__dirname, 'dist') // 輸出文件路徑,必須是絕對(duì)路徑,因此引用node的path模塊
}
}
SourceMap配置
Webpack打包后如果文件出錯(cuò)會(huì)把錯(cuò)誤指向打包后的文件中的某一行,而我們更需要知道是源文件哪一行出錯(cuò),這時(shí)就需要配置source-map ,在moudule.exports加入以下配置項(xiàng)
mode: 'development', // 表示是開(kāi)發(fā)環(huán)境,js文件不壓縮,設(shè)為 production 生產(chǎn)環(huán)境 則會(huì)壓縮
devtool: 'cheep-module-eval-source-map' // 開(kāi)發(fā)環(huán)境的最佳配置
//devtool: 'cheep-module-source-map', 生產(chǎn)環(huán)境的source-map的最佳配置
devtool配置項(xiàng)中
-
cheep表示只具體到某一行不具體到某一列,且不檢測(cè)loader的錯(cuò)誤,有助于加快編譯速度; -
module檢測(cè)loader的錯(cuò)誤,因此錯(cuò)誤更全,方便快速查找錯(cuò)誤 ; -
eval表示soucemap的映射代碼放到打包后的js文件中,而不是生成source.map.js文件; -
souce-map指將錯(cuò)誤映射到具體源文件上
熱加載
當(dāng)希望更改源文件時(shí)能自動(dòng)重新打包文件有兩種方法,第一種是在package.json里配置scripts
scripts: {
watch: 'webpack --watch'
}
即可實(shí)現(xiàn)效果,缺點(diǎn)是還是得手動(dòng)刷新頁(yè)面,不夠智能化,因此推薦的事第二種方法,使用webpack-dev-server,npm install webpack-dev-server后,增加配置項(xiàng):
devServer: {
contentBase: './dist', // 設(shè)置實(shí)時(shí)監(jiān)聽(tīng)打包文件的目錄
open: true, // 自動(dòng)打開(kāi)瀏覽器
port: 8080, // 端口
hot: true, // 啟動(dòng)模塊熱更新
hotOnly: true // 當(dāng)模塊熱更新失敗時(shí)瀏覽器也不自動(dòng)刷新
// proxy 可以配置跨域
}
當(dāng)需要更改css文件時(shí)頁(yè)面不刷新,則需要設(shè)置hot,啟動(dòng)HotModuleReplacement:先引入webpack模塊:const webpack = require('webpck'),再引入插件
plugins: [
new webpack.HotModuleReplacementPlugin()
]
之后在package.json里配置啟動(dòng)腳本
"scripts": {
"start": 'webpack-dev-server'
}
運(yùn)行npm run start即可熱加載網(wǎng)頁(yè)
識(shí)別打包 js 文件,編譯 es6
當(dāng)打包 js文件時(shí)需要配置模塊規(guī)則識(shí)別
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/, // 忽略依賴插件目錄的識(shí)別
loader: 'babel-loader' // 但需要編譯es6語(yǔ)法時(shí)需要引入babel
}]
}
編譯es6用的babel需要在根目錄創(chuàng)建配置文件,.babelrc
{
presets: [
[
"@babel/preset-env", {
targets: {
chrome: "67" // 谷歌瀏覽器自動(dòng)編譯es6語(yǔ)法,因此不用babel轉(zhuǎn)換
},
useBuiltIns: "usage" // 按需引入map、Promise等低版本瀏覽器沒(méi)有的對(duì)象
}]
]
}
在IE低版本瀏覽器中是沒(méi)有map、Promise等對(duì)象的,因此需要借用@babel/polyfill,npm install @babel/preset-env @babel/polyfill -D,之后在js文件中import "@babel/polyfill"即可,但有時(shí)我們開(kāi)發(fā)開(kāi)源組件時(shí)不希望polyfill污染全局變量,這是就需要另外一種配置方案,npm install -D @babel/plugin-transform-runtime @babel/runtime-corejs2 ,更改.babelrc配置為
{
"plugins": [
[
"@babel/plugin-transform-runtime", {
"corejs": 2, // 設(shè)為2才可以引入map等對(duì)象
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
識(shí)別打包圖片、字體
npm install -D url-loader file-loader,兩個(gè)loader均有將圖片添加到dist目錄里的功能。增加模塊識(shí)別規(guī)則:
module: {
rules: [
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader', // 功能跟file-loader差不多,區(qū)別是有轉(zhuǎn)換base64的功能
options: {
name: '[name]_[hash].[ext]', // ext 是保留源文件后綴
outputPath: 'images/', // dist 目錄下的images文件夾
limit: 10240 // 10kb以下的圖片自動(dòng)轉(zhuǎn)換為base64編碼插入到html中,其他正常生成圖片
}
}
}, {
test: /\.(eot/ttf/svg)$/,
use: {
loader: 'file-loader'
}
}
]
}
識(shí)別打包c(diǎn)ss、scss文件
npm i -D css-loader style-loader sass-loader postcss-loader ,添加模塊識(shí)別規(guī)則:
module: {
rules: [
{
test: /\.scss$/,
use: [ // 從下至上,從右到左執(zhí)行l(wèi)oader
'style-loader', // 將 css 插入到style標(biāo)簽中
{
loader: 'css-loader', // 解析css文件,包括對(duì)應(yīng)引用關(guān)系
options: {
importLoaders: 2
}
},
'sass-loader', // 解析sass,注意安裝的時(shí)候要安裝node-sass,sass-loader
'postcss-loader' // 添加css前綴,要有postcss.config.js配置上插件
]
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
}
]
}
postcss.config.js代碼如下
module.exports = {
plugins: [
require('autoprefixer')
]
}
生成 html
為了打包后自動(dòng)生成html文件并引入打包的js文件,需要安裝另一個(gè)插件,npm i -D html-webpack-plugin ,引入插件const HtmlWebpackPlugin = require('html-webpack-plugin'),增加插件配置項(xiàng)
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html' // 引用html模板,之后生成的html則會(huì)按照此模板生成并且自動(dòng)引入打包后的js文件
})
]
打包前自動(dòng)清除dist目錄
打包前最好能自動(dòng)清除dist 目錄,防止冗余文件,npm i -D clean-webpack-plugin,引入插件const CleanWebpackPlugin = require('clean-webpack-plugn'),添加插件配置
plugins: [
new CleanWebpackPlugin(['dist'])
]
編譯 React 代碼文件
npm i --save react react-dom后即可編寫(xiě)React代碼
import React, { Component } from 'react'
import ReactDom from 'react-dom'
class App extends Component {
render() {
return <div>Hello World</div>
}
}
ReactDom.render(<App />, document.getElementById('root'))
編譯React代碼則還需要npm i --save @babel/preset-react,并在.babelrc中的presets數(shù)組里增加一項(xiàng)"@babel/preset-react"即可正常編譯
總結(jié)
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: 'cheep-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: [ // 從下至上,從右到左執(zhí)行l(wèi)oader
'style-loader', // 將 css 插入到style標(biāo)簽中
{
loader: 'css-loader', // 解析css文件,包括對(duì)應(yīng)引用關(guān)系
options: {
importLoaders: 2
}
},
'sass-loader', // 解析sass,注意安裝的時(shí)候要安裝node-sass,sass-loader
'postcss-loader' // 添加css前綴,要有postcss.config.js配置上插件
]
},
{
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')
}
}