webpack版本:4.8.3
webpack-cli版本:2.1.3
1.全局安裝webpack和webpack-cli
cnpm i webpack webpack-cli -g
2.新建一個項目, 然后初始化
cnpm init
然后會生成一個package.json和 package-lock.json
3.在項目本地安裝webpack和webpack-cli
cnpm i webpack webpack-cli -D
注: -D是--save-dev的縮寫
-S是--save的縮寫
區(qū)別:-D是只在開發(fā)環(huán)境即dev中使用茅坛,項目發(fā)布以后就不會使用到冠息,如babel,loader等
-S是在開發(fā)和正式環(huán)境都會用到役衡,如jq,Vue等
4.打包第一個js文件
在根目錄新建一個hello.js文件薪棒,然后執(zhí)行
webpack hello.js hello.bundle.js
會得到一個警告一個錯誤
這是因為webpack4與之前不太一樣
webpack4.x的打包已經(jīng)不能用
webpack 文件a 文件b
的方式手蝎,而是直接運行
webpack --mode development(開發(fā)環(huán)境)
或者
webpack --mode production(發(fā)布模式)
榕莺,這是 webpack 4 引入的模式,包括 development棵介、production钉鸯、none 三個值,我們不傳入值的話邮辽,默認(rèn)使用 production進(jìn)行打包唠雕。
我們可以在package.json,script字段中添加以下設(shè)置:
"dev":"webpack --mode development", "build":"webpack --mode production"
這樣吨述,我們就能直接使用命令 npm run dev 或 npm run build 來進(jìn)行文件的打包處理岩睁。
webpack4.x會以項目根目錄下'./src/index.js'作為入口,單單創(chuàng)建src文件夾或者沒有index.js文件都會報錯揣云,輸出路徑是'./dist/main.js'捕儒,dist目錄及main.js會自動生成。
5.打包一個css文件
安裝
css-loader:使webpack可以處理css文件
style-loader:新建一個style標(biāo)簽邓夕,把css-loader處理過的文件放進(jìn)去刘莹,然后插入到HTML標(biāo)簽中
第一種方法:
在js文件中引入css文件,然后在文件名之前添加對應(yīng)的loader
require('style-loader!css-loader!./style.css')
第二種方法:
在執(zhí)行webpack命令時添加
webpack --mode development --module-bind "css=style-loader!css-loader"
其他的一些參數(shù)
--watch:監(jiān)控文件變化焚刚,一旦文件有變化点弯,就重新構(gòu)建。但默認(rèn)情況下矿咕,watch 選項是禁用的抢肛。
--progerss:會出現(xiàn)打包過程,有百分比進(jìn)度條
--display-modules:會把所有打包的模塊列出來
--display-reasons:會把打包的原因列出來
第三種方法:
添加webpack配置文件痴腌,稍后會寫出雌团。
6.添加配置文件
webpack4學(xué)習(xí)了parcel的0配置燃领,所以也可以不需要配置文件
這里webpack的配置文件并沒有太大變化
// 單入口文件
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
}
}
// 多入口文件
const path = require('path')
module.exports = {
entry: {
main: './src/index.js',
a: './src/a.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
}
}
注意:1.輸出路徑是path.resolve(__dirname, 'dist')
2.多文件的輸出文件名不能固定
3.如果不寫入口出口路徑則使用webpack4默認(rèn)的路徑
7.添加加載loaders
1.預(yù)處理css士聪,less
安裝less,less-loader猛蔽,css-loader剥悟,style-loader,postcss-loader和autoprefixer
cnpm install less less-loader css-loader style-loader postcss-loader autoprefixer -D
然后添加模塊曼库,規(guī)則
module: {
rules: [
{
test: /\.less$/,
loader: 'style-loader!css-loader!postcss-loader!less-loader' // 從右到左執(zhí)行区岗,所以注意順序
}
]
}
為了加webkit等前綴需要在webpack.config同級下創(chuàng)建一個postcss.config.js文件導(dǎo)入autoprefixer自動補(bǔ)全
module.exports = {
plugins: [
require('autoprefixer')
]
}
還需在package.json文件中添加判斷瀏覽器版本
"browserslist": [
"> 1%", // 全球瀏覽器使用率大于1%,最新兩個版本并且是IE8以上的瀏覽器毁枯,加前綴
"last 2 versions",
"not ie <= 8"
]
8.加入babel對es6語法進(jìn)行轉(zhuǎn)譯
cnpm install babel-loader babel-core babel-preset-env --save-dev
{
test: /\.js$/, // 匹配js文件
loader: 'babel-loader',
exclude: path.resolve(__dirname, 'node_modules'), //匹配時忽略這個目錄慈缔,提高打包速度
include: path.resolve(__dirname, 'src'), // 匹配時查找的范圍
query: {
presets: ['env']
}
}
9.開啟實時更新
安裝wbepack-dev-server
cnpm i webapck-dev-server -D
為了每次編譯完成后刪除上次打包的結(jié)果,添加刪除插件clean-webpack-plugin种玛,但是他也會刪除我們的index.html藐鹤,所以還需要安裝自動生成html插件
cnpm i clean-webpack-plugin html-webpack-plugin -D
const Webpack = require('webpack')
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// devServer和plugins是與module同級的
entry:,
output: ,
module: {
rules: []
},
devServer: {
// 設(shè)置服務(wù)器訪問的基本目錄
contentBase: path.resolve(__dirname, 'dist'), //最好設(shè)置成絕對路徑
// 設(shè)置服務(wù)器的ip地址,可以是localhost
host: 'localhost',
// 設(shè)置端口
port: 8090,
// 設(shè)置自動打開瀏覽器
open: true,
// 設(shè)置自動更新
hot: true
},
plugins: [
new Webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin(['dist']), //傳入數(shù)組,指定要刪除的目錄
new HtmlWebpackPlugin({
template: './index.html', // 會與根目錄下的index.html相關(guān)聯(lián)瓤檐,把根目錄下index的東西都放到生成的HTML中
filename: 'index.html', // 生成的HTML名,路徑為上面output中的path娱节,不填默認(rèn)是index.html
title: '測試webpack',
hash: true,
chunks: ['main'], // 多頁面分別引入自己的js
minify: {
collapseWhitespace: true, //折疊空白區(qū)域 也就是壓縮代碼
removeComments: true, //移除HTML中的注釋
}
})
]
注意:熱更新只針對js文件和樣式文件挠蛉,html不能熱更新
10.仔細(xì)講下html-webpack-plugin
多頁面時需要寫多個new HtmlWebpackPlugin
new HtmlWebpackPlugin({
template: './index.html', // 會與根目錄下的index.html相關(guān)聯(lián),把根目錄下index的東西都放到生成的HTML中
filename: 'index.html', // 生成的HTML名肄满,路徑為上面output中的path谴古,不寫默認(rèn)為index.html
title: '測試webpack',
hash: true,
//inject: 'body', //指定鏈接注入在<head>標(biāo)簽中還是<body>標(biāo)簽中,為false值時表示不自動注入文件中稠歉,需要手動設(shè)置
chunks: ['main'], // 多頁面分別引入自己的js
minify: {
collapseWhitespace: true //折疊空白區(qū)域 也就是壓縮代碼
}
}),
new HtmlWebpackPlugin({
template: './index.html', // 會與根目錄下的index.html相關(guān)聯(lián)掰担,把根目錄下index的東西都放到生成的HTML中
filename: 'a.html', // 生成的HTML名,路徑為上面output中的path轧抗,不寫默認(rèn)為index.html
title: '測試webpack',
hash: true,
//inject: 'body', //指定鏈接注入在<head>標(biāo)簽中還是<body>標(biāo)簽中恩敌,為false值時表示不自動注入文件中,需要手動設(shè)置
chunks: ['main', 'a'], // 多頁面分別引入自己的js
minify: {
collapseWhitespace: true //折疊空白區(qū)域 也就是壓縮代碼
}
})
還可通過這種方式自己引入
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
<script type="text/javascript" src="<%=htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
<% } %>
11.添加vue
安裝vue
cnpm install vue -S
安裝vue-loader
cnpm install vue-loader -D
創(chuàng)建一個.vue后綴的文件横媚,然后修改main.js文件
import Vue from 'vue'
import App from './app.vue'
const root = document.createElement('div')
document.body.appendChild(root)
new Vue({
render: (h) => h(App)
}).$mount(root)
然后修改webpack.config文件纠炮,添加vue-loader
注意:vue-loader15.0版本之后需要獨立引入VueLoaderPlugin
const VueLoaderPlugin = require('vue-loader/lib/plugin')
{
test: /\.vue$/,
loader: 'vue-loader'
}
如果你沒有安裝css預(yù)處理,或者在style部分沒有添加lang=*
灯蝴,這時打包會報錯
明顯這是未對vue文件中的style部分正確的編譯恢口,所以安裝vue-style-loader并添加loader
cnpm install vue-style-loader -D
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
注意:如果在main.js中的寫法和vue-cli官方腳手架一樣是這樣的
new Vue({
el: '#app',
components: {App},
template: '<App/>'
})
則運行dev會出現(xiàn)警告
如果在代碼中要使用到template編譯模版(比如傳入一個字符串給 template 選項,或掛載到一個元素上并以其 DOM 內(nèi)部的 HTML 作為模板)穷躁,則需要完整版的vue耕肩。
當(dāng)使用 vue-loader 或 vueify 的時候,*.vue 文件內(nèi)部的模板會在構(gòu)建時預(yù)編譯成 JavaScript问潭。你在最終打好的包里實際上是不需要編譯器的猿诸,所以只用運行時版本即可。
因為運行時版本相比完整版體積要小大約 30%狡忙,所以應(yīng)該盡可能使用這個版本梳虽。如果你仍然希望使用完整版,則需要在webpack.config里配置一個別名:
module.exports = {
// ...
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}
12.在vue文件里添加圖片
在vue文件中添加圖片灾茁,然后打包會報錯
提示我們?nèi)鄙賔ile-loader窜觉,安裝即可,且不用添加loader到webpack.config文件
cnpm i file-loader -D
打包時對圖片的編譯我們使用url-loader北专,他會將圖片轉(zhuǎn)為base64格式添加到網(wǎng)頁中禀挫,url-loader也依賴于file-loader,所以也需要安裝file-loader
cnpm i url-loader file-loader -D
{
test: /\.(gif|jpg|jpeg|png|svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024, //表示圖片最大為1024KB
name: '[name].[ext]' // 生成的文件名
}
}
]
}
13.根據(jù)多環(huán)境選擇不同的配置
安裝cross-env
cnpm i cross-env -D
修改package.json文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "cross-env NODE_ENV=development webpack-dev-server --mode development",
"build": "cross-env NODE_ENV=production webpack --mode production"
},
這里的NODE_ENV會添加到process.env上拓颓,怎么添加呢语婴?
const isDev = process.env.NODE_ENV === 'development'
const devAPI = '"http://localhost:8080"'
const proAPI = '"http://localhost:3000"'
// 注意一定是單引號加雙引號的形式
...
plugins: {
...
new Webpack.DefinePlugin({
'process.env': {
NODE_ENV: isDev ? '"development"' : '"production"',
API_HOST: isDev ? devAPI : proAPI
}
})
...
}
另外可以將整個對象命名為config,然后根據(jù)isdev去給config添加配置,最后再將config暴露出去
const config = {......}
if(isDev){
config.devtool = '#cheap-module-eval-source'
}
module.exports = config
14.將css單獨打包
安裝extract-text-webpack-plugin
注意:webpack4中需要使用的extract-text-webpack-plugin版本比較高砰左,需要指定版本
查看包的所有版本
cnpm view extract-text-webpack-plugin versions
安裝包的最新版本
cnpm i extract-text-webpack-plugin@next -D
const ExtractTextPlugin = require('extract-text-webpack-plugin')
...
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
},
},
'less-loader'
]
})
}
...
plugins: {
new ExtractTextPlugin({
filename: 'css/app.[hash].css',
chunkFilename: 'css/app.[contenthash].css'
}
webpack4中extract-text-webpack-plugin已經(jīng)不再被推薦使用画拾,推薦使用新的插件mini-css-extract-plugin
安裝mini-css-extract-plugin
cnpm i mini-css-extract-plugin -D
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
...
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
},
},
'less-loader'
]
},
...
new MiniCssExtractPlugin({
filename: 'static/css/app.[hash].css',
chunkFilename: 'static/css/app.[contenthash].css'
})
15.將第三方庫單獨打包(不是很明白)
因為CommonsChunkPlugin被刪除, 改為內(nèi)置的api--optimization,同plugins同級
...
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'initial',
minChunks: 2
},
}
}
},