webpack的兩大特色:1模塊化 2打包
做用:
1將sass/less 等預編譯的css語言轉換成瀏覽器識別的css文件
2可以將多個預編譯文件打包成一個文件
3 打包image/styles/assets/scrips/等前端經常使用的文件
4 搭建開發環境開啓服務器
5 監視文件改動,熱部署。
6 將單文件組件(*.vue)類型的文件,轉化成瀏覽器識別的內容javascript
$ npm i -D webpack webpack-cli //-D 安裝在開發環境複製代碼
WebPack 4.X 支持零配置 (咱們先來嘗試一下webpack如何實現打包部署)css
$ npx webpack //基於npx執行了webpack命令,而這個命令就是實現打包部署的
查找順序:
- 找到node_modules/.bin - 要求咱們得有 webpack.cmd 的文件 - 執行 webpack.cmd 複製代碼
知識點:自npm5.2.0開始之後,自動安裝了npx( npx 會幫你執行依賴包裏的二進制文件)
html
舉個例子:(在npx沒有出現以前)前端
npm i webpack -D //非全局安裝//若是要執行 webpack 的命令./node_modules/.bin/webpack -v複製代碼
有了npx後vue
npm i webpack -D //非全局安裝npx webpack -v 複製代碼
npx 會自動查找當前依賴包中的可執行文件,若是找不到,就會去 PATH 裏找。若是依然找不到,就會幫你安裝。
java
雖然webpack支持零配置,可是平常開發中咱們也會根據需求來本身定義基礎配置node
在根目錄下建立webpack.config.js文件:
jquery
/* * 在這個文件中設置咱們自定義的打包規則 * 1.全部的規則都寫在module.exports={}中 */
//由於須要用node中的path內置模塊(內置模塊,無需下載)
let path = require('path');
module.exports = {
//=>打包模式 開發環境development 生產環境production
mode: 'production',
//=>入口
entry: './src/index.js',
//=>輸出
output: {
//=>輸出文件的文件名
filename: 'bundle.min.[hash].js',
//=>輸出目錄的"絕對路徑"
path: path.resolve(__dirname, 'dist')
}
}複製代碼
咱們能夠在根目錄下package.json文件中webpack
//package.json
"scripts": {
"serve": "webpack-dev-server --config webpack.config.development.js", "build": "webpack --config webpack.config.development.js"}
//這樣咱們之後就能夠經過 yarn或者npm直接執行 serve/build 了,方便了不少複製代碼
是一個用來快速搭建本地運行環境的工具。命令簡單webpack-dev-server
或配置命令腳本快捷運行(在👆3中 已經配置了serve,咱們之後能夠直接運行 serve)git
安裝
$ yarn add webpack-dev-server -D複製代碼
//=>關於webpack-dev-server的一些配置 執行命令:webpack-dev-server --config xxx.js(特色:服務器啓動後,默認是不關閉的,當咱們修改SRC中的文件時,它會自動進行編譯,而後自動刷新瀏覽器) devServer: { port: 3000, //=>建立服務指定的端口號 progress: true, //=>顯示打包編譯的進度 contentBase: './build', //=>指定當前服務處理資源的目錄 open: true //=>編譯完成後會自動打開瀏覽器 }複製代碼
$ npm run serve $ yarn serve $ npx webpack-dev-server複製代碼
html-webpack-plugin
插件是用於編譯 Webpack
項目中的 html 類型的文件,若是直接將 html
文件置於 ./src
目錄中,用 Webpack
打包時是不會編譯到生產環境中的。由於 Webpack
編譯任何文件都須要基於配置文件先行配置的。
Webpack 插件使用三步曲:安裝>引入>配置
npm&yarn 安裝
$ npm install --save-dev html-webpack-plugin複製代碼
$ yarn add html-webpack-plugin --dev複製代碼
引入(接着在webpack.config.js 開始的地方引入)
let HtmlWebpackPlugin = require('html-webpack-plugin');複製代碼
配置
module.exports = {
...,
//=>在webpack中使用插件
plugins: [
//由於導入的插件是一個類,因此咱們用的時候須要new 一下
new HtmlWebpackPlugin({
//=>指定本身的模板
template: './src/index.html',
//=>輸出的文件名
filename: 'index.html',
//=>給引入的文件設置HASH戳(清除緩存的),也能夠在output中設置 filename: 'bundle.[hash].js' 來生成不一樣的文件
hash: true,
//=>控制是否以及以何種方式最小化輸出
//=>https://github.com/kangax/html-minifier
//控制壓縮
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true,
removeEmptyAttributes: true
}
})
]
}
複製代碼
官網: www.webpackjs.com/api/loaders…
安裝
$ yarn add css-loader style-loader less less-loader autoprefixer postcss-loader (等等) -D複製代碼
配置
module.exports = {
//=>配置模塊加載器LOADER
module: {
//=>模塊規則:使用加載器(默認從右向左執行,從下向上)
rules: [{
test: /\.(css|less)$/, //=>基於正則表達式匹配哪些模塊須要處理
use: [
"style-loader", //=>把CSS插入到HEAD中
"css-loader", //=>編譯解析@import/URL()這種語法
"postcss-loader", //=>設置前綴
{
loader: "less-loader",
options: {
//=>加載器額外的配置
}
}
]
}]
}
}
複製代碼
在 postcss.config.js 文件中
//這個文件須要配合postcss-loader使用
module.exports = {
plugins: [
require('autoprefixer')
]
};
複製代碼
在 package.json 文件的末尾加入
//像這些" > 1%", "last 2 versions" 都是查詢參數
"browserslist": [
"> 1%",
"last 2 versions"
]
複製代碼
安裝
$ yarn add mini-css-extract-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D複製代碼
引入
let MiniCssExtractPlugin = require('mini-css-extract-plugin'),
OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'),
UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');複製代碼
配置
module.exports = {
//=>設置優化項
optimization: {
//=>設置壓縮方式
minimizer: [
//=>壓縮CSS(可是必須指定JS的壓縮方式)
new OptimizeCssAssetsWebpackPlugin(),
//=>壓縮JS
new UglifyjsWebpackPlugin({
cache: true, //=>是否使用緩存
parallel: true, //=>是不是併發編譯
sourceMap: true, //=>啓動源碼映射(方便調試)
})
]
},
plugins: [
//=>使用插件
new MiniCssExtractPlugin({
//=>設置編譯後的文件名字
filename: 'main.css'
})
],
module: {
rules: [{
test: /\.(css|less)$/,
use: [
// "style-loader",
//=>使用插件中的LOADER代替STYLE方式
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"less-loader"
]
}]
}
}
複製代碼
(當咱們須要對於ES6中的一些語法進行處理)
安裝
$ yarn add babel-loader @babel/core @babel/preset-env @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime -D複製代碼
$ yarn add @babel/runtime @babel/polyfill複製代碼
$ yarn add eslint eslint-loader -D複製代碼
配置
module.exports = {
...,
module: {
rules: [...,{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
//=>轉換的語法預設(ES6->ES5)
presets: [
"@babel/preset-env"
],
//=>基於插件處理ES6/ES7中CLASS的特殊語法
plugins: [
["@babel/plugin-proposal-decorators", {
"legacy": true
}],
["@babel/plugin-proposal-class-properties", {
"loose": true
}],
"@babel/plugin-transform-runtime"
]
}
}], //=>, "eslint-loader"
//=>設置編譯時忽略的文件和指定編譯目錄
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
}]
}
}
複製代碼
(若是你想直接使用 jQuery或者 $)
安裝
$ yarn add expose-loader -D複製代碼
配置
//=>內聯加載器
import jquery from 'expose-loader?$!jquery'; //這句話的意思就是將jquery以$的形式暴露給window
{
//=>只要引入JQUERY就在全局注入$
test: require.resolve('jquery'),
use: ['expose-loader?$']
}
複製代碼
let webpack = require('webpack');
module.exports = {
plugins: [
//=>在每一個模塊中都注入$
new webpack.ProvidePlugin({
'$': 'jquery'
})
],
}
//=>頁面中
console.log($);//這樣就不會報錯了
複製代碼
(當咱們js中建立img,css設置圖片以及HTML頁面中寫入的圖片,能夠基於此方法壓縮)
安裝
$ yarn add file-loader url-loader html-withimg-loader -D複製代碼
配置
module.exports = {
...,
module: {
//=>模塊規則:使用加載器(默認從右向左執行)
rules: [..., {
//還有不少圖片格式。。。
test: /\.(png|jpg|gif)$/i,
use: [{
//=>把指定大小內的圖片BASE64
loader: 'url-loader',
options: {
limit: 200 * 1024,//=>只要圖片是小於200KB,在處理的時候直接給BASE64
outputPath:'/images'//控制打包後圖片所在的目錄
}
}],
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
}, {
//=>處理HTML文件中導入的IMG圖片
test: /\.html$/,
use: ['html-withimg-loader']
}]
}
}
複製代碼
module.exports = {
output: {
//=>配置引用前綴(全部資源前加這個地址)
publicPath: './'
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/main.css'
})
],
module: {
//=>模塊規則:使用加載器(默認從右向左執行)
rules: [...,{
test: /\.(png|jpg|gif)$/i,
use: [{
options: {
outputPath: 'images'
}
}]
}]
}
}複製代碼
到此 webpack 的各類配置 已經能夠完成平常開發了
在寫這個文章以前我只是知道能夠用vue-cli直接生成一個vue項目的架構,並不明白,他到底是怎麼運行的☺
npm install -g @vue/cli //-g 全局
# OR
yarn global add @vue/cli //基於yarn安裝(須要安裝yarn)複製代碼
$vue create [項目名稱](要遵循npm包的名稱規範:數字或者小寫字母)複製代碼
你會被提示選取一個 preset。你能夠選默認的包含了基本的 Babel + ESLint 設置的 preset,也能夠選「手動選擇特性」來選取須要的特性。
選擇第二個 Manually select features
能夠按照這個 配置本身須要的 方向鍵 ↑↓ 能夠選擇 space 空格鍵確認 除了默認選擇的兩項我還選擇了Router,Vuex,CSS Pre-processore(根據本身需求選擇,後期也能夠本身添加)
等待安裝,項目基本就算建立完成了
而後你就看到本身建立的項目了 用編輯器打開hello--xiaokai文件
你能夠打開本身編輯器的終端 我用的是VScode ctrl+` 而後輸入
$npm run serve 或者 $yarn serve複製代碼
就能夠把項目預覽了
在生產模式下,把寫好的內容進行編譯打包,最後部署到服務器上
$npm run build or $yarn build複製代碼
/* 在這個文件中設置咱們自定義的打包規則 1. 全部的規則都寫在module.exports={}中 */
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let MiniCssExtractPlugin = require('mini-css-extract-plugin'), //把css單獨分離出來
OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'), //壓縮css
UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin'); //壓縮js
let webpack = require('webpack');
//導入進來的插件都是一個類 new HtmlWebpackPlugin({});
module.exports = {
//配置優化規則
optimization: {
//設置壓縮方式
minimizer: [
//壓縮css (產生問題:JS壓縮不在執行本身默認的壓縮方式了,也走的是這個插件,從而致使沒法壓縮,因此必須設置JS的壓縮方式)
new OptimizeCssAssetsWebpackPlugin(),
//壓縮js
new UglifyjsWebpackPlugin({
cache: true, //是否使用緩存
parallel: true, //是不是兵法編譯
sourceMap: true, //啓動源碼映射(方便調試)
})
]
},
//配置環境 開發環境development 生產環境production(默認)
mode: 'production',
//入口 @babel6
entry: ['@babel/polyfill', './src/index-my.js'],
//出口
output: {
//輸出文件的文件名
//bundle.min.[hash].js 讓每一次生成的文件名都帶着hash值
filename: 'bundle.min.js',
// filename: 'bundle.min.[hash].js',
//輸出的目錄必須是絕對路徑,__dirname當前目錄
path: path.resolve(__dirname, 'dist'),
publicPath: './' //給編譯後引入資源地址前面設置的前綴
},
//關於webpack-dev-server的一些配置 執行命令:webpack-dev-server --config xxx.js (特色:服務啓動後,默認是不關閉的,當咱們修改src中的源文件,他會自動進行編譯,而後自動刷新瀏覽器,相似於vscode中的Live Server插件,實時刷新)
devServer: {
//建立服務指定的端口號
port: 3000,
//顯示打包編譯進度
progress: true,
//指定當前服務處理資源的目錄
contentBase: './dist',
//編譯完成後,自動打開瀏覽器
open: true
},
//使用插件 (數組)
plugins: [
new HtmlWebpackPlugin({
//不指定模版會按照默認模版建立一個html頁面,固然真實項目中通常都是把本身寫好的html進行編譯
template: './src/index.html',
//輸出的文件名
filename: 'index.html',
//讓咱們引入js後面加上hash戳(清除緩存),可是真實項目中咱們通常都是每一次編譯生成不一樣的js文件引入
hash: true,
//控制壓縮
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true,
removeEmptyAttributes: true
}
}),
new MiniCssExtractPlugin({
//指定輸出的文件名
filename: 'main.min.css'
}),
//在每一個模塊中都注入$
new webpack.ProvidePlugin({
'$': 'jquery'
}),
],
//使用加載器loader處理規則
module: {
rules: [{
//基於正則匹配處理哪些文件
test: /\.(css|less)$/,
//使用哪個加載器,控制使用的loader(有順序的:從右到左執行)
use: [
// "style-loader", //把編譯好的css插入到頁面的head中(內嵌式)
MiniCssExtractPlugin.loader, //使用插件中的loader代替style方式
"css-loader", //編譯解析@import/URL()這種語法
// "postcss-loader",//設置前綴的加載器
{
loader: "postcss-loader",
options: {
ident: 'postcss',
plugins: [
require('autoprefixer')
]
}
},
{
loader: "less-loader", //編譯less
options: {
//加載額外的配置
}
}
]
}, {
test: /\.js$/,
//處理編譯JS的loader
use: [{
loader: 'babel-loader',
options: {
//轉換的語法預設(ES6->ES5)
presets: [
"@babel/preset-env"
],
//=>基於插件處理ES6/ES7中CLASS的特殊語法
plugins: [
["@babel/plugin-proposal-decorators", {
"legacy": true //處理裝飾器
}],
["@babel/plugin-proposal-class-properties", {
"loose": true //處理屬性
}],
"@babel/plugin-transform-runtime"
]
}
}],
//設置編譯時忽略的文件和指定編譯目錄
include: path.resolve(__dirname, 'src'), //編譯的
exclude: /node_modules/ //忽略的·
}, {
//圖片處理
test: /\.(png|jpg|gif|jpeg|ico|webp|bpm)$/i,
use: [{
loader: 'url-loader',
options: {
//只要圖片小於200KB,在處理的時候直接base64
limit: 2 * 1024,
//控制打包後圖片所在的目錄
outputPath: 'images'
}
}]
}, {
//處理HTML文件中導入的img文件
test: /\.(html|htm|xml)$/i,
use: ['html-withimg-loader']
}]
}
}
複製代碼
----------感謝導師-周嘯天