首頁>技術>

什麼是webpack ,本質上,webpack 是一個現代 JavaScript 應用程式的靜態模組打包器(module bundler)。當 webpack 處理應用程式時,它會遞迴地構建一個依賴關係圖(dependency graph),其中包含應用程式需要的每個模組,然後將所有這些模組打包成一個或多個 bundle.webpack 有哪些功能(程式碼轉換 檔案最佳化 程式碼分割 模組合併 自動重新整理 程式碼校驗 自動釋出)首先學習webpack 需要有簡單的node 基礎,開啟node官方網站進行安裝node, http://nodejs.cn/ 下載最新版node包並進行安裝

學習目標:

webpack 常見配置 webpack高階配置webpack最佳化策略AST抽象語法樹webpack中的Tapable掌握webpack流程 手寫 webpack手寫webpack中常見的loader手寫webpack 中常見的plugin

webpck--->基礎搭建與使用:

安裝完畢在終端 快速建立node專案 執行命令npm init -y 生成packge.json在當前目錄安裝本地webpack終端執行命令:npm i webpack webpack-cli -di 表示 install , d表示當前是開發環境安裝完成會產生node_modules檔案webpack 可以進行0配置 並且webpack是打包工具(預設是js模組 透過入口進行打包輸出打包後js結果)。建立src目錄 --> 建立index.js -> 輸出:console.log('hello webpack');npx 語法進行把index.js 進行打包終端執行命令:npx webpack我們發現當前目錄生成了一個dist 目錄並且建立了一個main.js(如圖:)

執行順序:(預設找node_modules--->bin檔案 --> webpack檔案 )

這裡我們明白了安裝webpack 必須安裝他的依賴 webpack-cliwebpack打包預設支援js模組化 ->類似於common.js

webpack:兩種默兩種模式如果沒有建立webpack.config.js 配置檔案指定mode (production/development)生成模式或開發模式,打包執行會直接預設生產模式打包並且進行壓縮。這裡說一下webpack配置檔案的預設名稱有兩種 (webpack.config.js / webpackfile.js 一般情況下我們會選擇前一種)

如何手動配置webpack呢?其實比較簡單

(1)建立webpack.config.js 配置檔案 由於webpack是node.js的框架所以配置檔案中要採用node語法來進行編輯。

const path = require("path"); //webpack內部方法path元件

module.exports = {

mode: "development", //打包模式 development開發模式

entry: "./src/index.js", //入口檔案指定

output: { //出口檔案配置 配置出口打包路徑

filename: "build.js", //打包後的檔名稱

path: path.resolve(__dirname, "build") //resolve絕對路徑引入

}

}

接收到modules 裡 先定義一個快取物件 installedModules先定一個快取目的是如果我當前模組載入完成沒有必要再進行載入webpack_require 實現了一個require方法因為瀏覽器無法直接執行node的require方法

執行__webpack_require__ 發現接收了一個入口模組

終端執行:npx webpack , 發現我們打包當前目錄產生了資料夾build目錄分析了一下打包檔案是不是感覺webpack 原始碼沒有想象的那麼難繼續我們webpack 的探索之旅。如何更改webpack配置檔名稱呢其實重新命名webpack.config.js (webpack.test.js)執行命令:

npx webpack --config webpack.test.js 發現可以執行webpack打包。這樣打包我發現命令很長所以我們利用packge.json 來配置打包指令碼在scripts-->新增build.

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"build": "webpack --config webpack.config.js"

}

終端執行 npm run build 發現執行打包結果一樣.

(2)webpack 其他配 -->置外掛的使用不會生成檔案會生成記憶體中的打包安裝webpck內建服務 webpack-dev-server 好處是終端執行命令: npm i webpack-dev-server -d -save安裝完成可以執行 npx webpack-dev-server 按提示開啟http://localhost:8080/如何配置開發服務執行目錄可以在配置檔案中新增在webpack.config.js新增devServer

const path = require("path");

module.exports = {

mode: "development", //打包模式

entry: "./src/index.js", //入口檔案指定

output: { //出口檔案配置 配置出口打包路徑

filename: "build.js", //打包的檔名稱

path: path.resolve(__dirname, "build") //resolve絕對路徑引入

},

devServer: { //開發伺服器配置

contentBase: "./build", //指向打包目錄

port: 3000, //服務埠號

progress: true, //打包進度

open: true, //是否開啟瀏覽器

compress: false //是否壓縮

}

}

在packge.json中新增start 啟動服務指令碼

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"build": "webpack --config webpack.config.js",

"start":"webpack-dev-server"

}

執行 npm run start 發現沒有自動建立index.html 不能直觀看到我們程式碼在瀏覽器的執行。在src目錄下建立html模板 index.html 並安裝 html-webpack-plugin 外掛

終端執行: npm i -d html-webpack-plugin在webpack.config.js 下新增外掛配置plugins

const path = require("path");

const HtmlWebPackPlugin = require("html-webpack-plugin");

module.exports = {

mode: "development", //打包模式

entry: "./src/index.js", //入口檔案指定

output: { //出口檔案配置 配置出口打包路徑

filename: "build[hash:8].js",

path: path.resolve(__dirname, "build") //resolve絕對路徑引入

},

devServer: { //開發伺服器配置

contentBase: "./build", //指向打包目錄

port: 3000, //服務埠號

progress: true, //打包進度

open: true, //是否開啟瀏覽器

compress: false //是否壓縮

},

//外掛

plugins: [ //陣列形式 存放所有的webpack外掛

new HtmlWebPackPlugin({

filename: "index.html", //生成打包檔名

template: "./src/index.html", //模板路徑

minify: { //生產模式可以進行配置

collapseWhitespace: true //摺疊空行

},

hash:true, //新增雜湊值

})

]

}

終端執行打包測試:npm run build (build目錄下生成了我們想要生成的index.html檔案)

樣式的配置 webpack配置css模組:

配置樣式需要一個合適loader,loader會將我們的樣式檔案解析成模組(module)終端:npm i -d --save css-loader style-loader如何使用樣式loader進行配置呢?我們先在src下建index.css並給body賦予簡單樣式在webpack.config.js 進行簡單配置css-loader主要解析我們樣式中@import語法,style-loader是把css樣式插入head標籤中.

module: { //新增模組模組是物件

rules: [ //規則 css-loader主要解析我們樣式中@import語法

{

test: /\.css$/,

use: ["style-loader", "css-loader"] //執行順序是從右向左執行 - >從下到上

}

]

}

在index.js中引入樣式檔案 import './index.css'終端執行:npm run start 樣式生效了同樣我們也有對應的less less-loader終端:npm i -d --save less less-loader在這裡說一下loader 的另一種寫法物件寫法可以給loader新增一些屬性options

module: { //新增模組模組是物件

rules: [ //規則 css-loader主要解析我們樣式中@import語法

{

test: /\.css$/,

use: [

{

loader: "style-loader",

options: {

insertAt: "top" //把標籤插入頂部

}

},

"css-loader"

] //執行順序是從右向左執行 - >從下到上

},

{

test: /\.less$/,

use: [

{

loader: "style-loader",

options: {

insertAt: "top" //把標籤插入頂部

}

},

"css-loader",

"less-loader"

] //執行順序是從右向左執行 - >從下到上

}

]

}

css 樣式的抽離 安裝抽離外掛 mini-css-extract-plugin npm i -d --save mini-css-extract-plugin引入外掛並在配置檔案中進行配置

const path = require("path");

const HtmlWebPackPlugin = require("html-webpack-plugin");

const MinCssExtractPlugin = require("mini-css-extract-plugin"); //抽離css外掛

module.exports = {

mode: "development", //打包模式

entry: "./src/index.js", //入口檔案指定

output: { //出口檔案配置 配置出口打包路徑

filename: "[name][hash:8].js",

path: path.resolve(__dirname, "build") //resolve絕對路徑引入

},

devServer: { //開發伺服器配置

contentBase: "./build", //指向打包目錄

port: 3000, //服務埠號

progress: true, //打包進度

open: true, //是否開啟瀏覽器

compress: false //是否壓縮

},

//外掛

plugins: [ //陣列形式 存放所有的webpack外掛

new HtmlWebPackPlugin({

filename: "index.html", //生成打包檔名

template: "./src/index.html", //模板路徑

minify: {

collapseWhitespace: true //摺疊空行

},

hash: true //新增雜湊值

}),

new MinCssExtractPlugin({

filename: "mian.css"

})

],

module: { //新增模組模組是物件

rules: [ //規則 css-loader主要解析我們樣式中@import語法

{

test: /\.css$/,

use: [

MinCssExtractPlugin.loader, //建立link標籤放入到main.css裡

"css-loader"

] //執行順序是從右向左執行 - >從下到上

},

{

test: /\.less$/,

use: [MinCssExtractPlugin.loader, "css-loader","less-loader"]

//執行順序是從右向左執行 - >從下到上

}

]

}

}

新增樣式字首 postcss-loader autoprefixernpm i postcss-loader autoprefixer -d

module: { //新增模組模組是物件

rules: [ //規則 css-loader主要解析我們樣式中@import語法

{

test: /\.css$/,

use: [

MinCssExtractPlugin.loader, //建立link標籤放入到main.css裡

"css-loader",

"postcss-loader"

] //執行順序是從右向左執行 - >從下到上

},

{

test: /\.less$/,

use: [

MinCssExtractPlugin.loader, //建立link標籤放入到main.css裡

"css-loader",

"postcss-loader",

"less-loader"

] //執行順序是從右向左執行 - >從下到上

}

]

}

注意postcss-loader需要新增一個配置檔案否則不會生效目錄建立postcss.config.js

module.exports = {

plugins: [require("autoprefixer")]

}

但是我們發現問題使用mini-css-extract-plugin外掛導致我們css不會被壓縮。npm 官網有給出To minify the output, use a plugin like optimize-css-assets-webpack-plugin. Setting optimization.minimizer overrides the defaults provided by webpack, so make sure to also specify a JS minimizer:

要使用optimize-css-assets-webpack-plugin 外掛接下來我們安裝配置一下.npm i -d optimize-css-assets-webpack-plugin

發現可以已經轉換es6語法 但是僅僅這樣不能轉換es6高階語法比如一些特殊的類函式

class Test {

// new Test() a =1 例項上新增a屬性 這個語法屬於es7語法打包時發現並不能解析

a = 1;

}

終端執行:npm run build 發現報錯提示安裝 @babel/plugin-proposal-class-properties

那我們按照要求按照查一下外掛 npm i -d @babel/plugin-proposal-class-properties 並進行一次配置

//在rules下新增配置

{

test: /\.js$/,

use: [

{

loader: "babel-loader",

options: { //轉化es5語法--presets預設

presets: ["@babel/preset-env"],

plugins: ["@babel/plugin-proposal-class-properties"]

}

}

]

},

還有一種寫法 裝飾器@Log打包也是不被解析的 在js 新增

//在rules下新增配置

{

test: /\.js$/,

use: {

{

loader: "babel-loader",

options: { //轉化es5語法--presets預設

presets: ["@babel/preset-env"],

plugins: [ //這裡要注意新增順序

["@babel/plugin-proposal-decorators", { legacy: true }],

["@babel/plugin-proposal-class-properties", { loose: true }]]

}

}

},

轉化完語法接下來看一下babel語法的校驗 @babel/plugin-transform-runtime @babel/runtime

{

test: /\.js$/,

use: {

loader: "babel-loader",

options: { //轉化es5語法--presets預設

presets: ["@babel/preset-env"],

plugins: [

["@babel/plugin-proposal-decorators", { legacy: true }],

["@babel/plugin-proposal-class-properties", { loose: true }],

[

"@babel/plugin-transform-runtime",

{

absoluteRuntime: false,

corejs: false,

helpers: true,

regenerator: true,

useESModules: false

}

]

]

}

},

include: path.resolve(__dirname, "src"), //只找__dirname - >src

exclude: /node_modules/ //忽略node_modulse

}

includes 例項方法不被解析 需要一個補丁模組@babel/polyfillnpm install --save @babel/polyfillBabel includes a polyfill that includes a custom regenerator runtime and core-js.使用可以直接在js 裡引入即可。接下來看一下程式碼校驗ESLint程式碼校驗工具終端安裝 npm i -d eslint eslint-loader根據專案需求下載對應的eslintrc.json

//程式碼校驗eslint

{

test: /\.js$/,

use: {

loader: "eslint-loader",

options: {

enforce: "pre" //強制執行順序

}

}

}

本文回顧 1、webpack基本功能 build.js 打包的原理及原始碼分析 2、webpack基礎配置及常用外掛配置安裝 3、loader的使用與配置樣式的處理 4、webpack最佳化項的簡單使用 5、babel語法轉換與使用 babel語法校驗 . 完成以上我相信大家可以掌握並搭建簡單webpack專案。

12
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • php 一步步實現mvc架構——路由篇