前言
什么是webpack 本質(zhì)上,webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)遞歸地構(gòu)建一個(gè)依賴(lài)關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個(gè)模塊,然后將所有這些模塊打包成一個(gè)或多個(gè) bundle。
webpack 有哪些功能(代碼轉(zhuǎn)換 文件優(yōu)化 代碼分割 模塊合并 自動(dòng)刷新 代碼校驗(yàn) 自動(dòng)發(fā)布)
首先學(xué)習(xí)webpack 需要有簡(jiǎn)單的node 基礎(chǔ) ,打開(kāi)node 官方網(wǎng)站進(jìn)行安裝node, http://nodejs.cn/ 下載最新版node包并進(jìn)行安裝。
webpack 常見(jiàn)配置 webpack高級(jí)配置
webpack優(yōu)化策略
AST抽象語(yǔ)法樹(shù)
webpack中的Tapable
掌握webpack流程 手寫(xiě) webpack
手寫(xiě)webpack中常見(jiàn)的loader
手寫(xiě)webpack 中常見(jiàn)的plugin
定義好學(xué)習(xí)目標(biāo)讓我們開(kāi)啟webpack 的新旅程。(本文學(xué)習(xí)主要針對(duì)webpack4.0 進(jìn)行學(xué)習(xí)講解)
webpck--->基礎(chǔ)搭建與使用:安裝完畢在終端 快速創(chuàng)建node項(xiàng)目 執(zhí)行命令npm init -y 生成packge.json
在當(dāng)前目錄安裝本地webpack
終端執(zhí)行命令:
npm i webpack webpack-cli -d
i表示install ,d表示當(dāng)前是開(kāi)發(fā)環(huán)境安裝完成會(huì)產(chǎn)生node_modules文件
webpack 可以進(jìn)行0配置 并且webpack是打包工具(默認(rèn)是js模塊 通過(guò)入口進(jìn)行打包輸出打包后js結(jié)果)。
創(chuàng)建src目錄 --> 創(chuàng)建index.js -> 輸出:console.log("hello webpack");
npx 語(yǔ)法進(jìn)行把index.js 進(jìn)行打包
終端執(zhí)行命令:
npx webpack
我們發(fā)現(xiàn)當(dāng)前目錄生成了一個(gè)dist 目錄并且創(chuàng)建了一個(gè)main.js(如圖:)
執(zhí)行順序:(默認(rèn)找node_modules--->bin文件 --> webpack文件 )
這里我們明白了安裝webpack 必須安裝他的依賴(lài) webpack-cli
webpack打包默認(rèn)支持js模塊化 ->類(lèi)似于common.js
webpack:兩種默兩種模式如果沒(méi)有創(chuàng)建webpack.config.js 配置文件指定mode (production/development)生成模式或開(kāi)發(fā)模式,打包運(yùn)行會(huì)直接默認(rèn)生產(chǎn)模式打包并且進(jìn)行壓縮。
這里說(shuō)一下webpack配置文件的默認(rèn)名稱(chēng)有兩種 (webpack.config.js / webpackfile.js 一般情況下我們會(huì)選擇前一種)
(1)創(chuàng)建webpack.config.js 配置文件 由于webpack是node.js的框架所以配置文件中要采用node語(yǔ)法來(lái)進(jìn)行編輯。
const path = require("path"); //webpack內(nèi)部方法path組件 module.exports = { mode: "development", //打包模式 development開(kāi)發(fā)模式 entry: "./src/index.js", //入口文件指定 output: { //出口文件配置 配置出口打包路徑 filename: "build.js", //打包后的文件名稱(chēng) path: path.resolve(__dirname, "build") //resolve絕對(duì)路徑引入 } };
我們分析一下build.js 打包出的結(jié)果,默認(rèn)下是一個(gè)匿名函數(shù) 并且接收兩個(gè)參數(shù) 接收一個(gè)對(duì)象,Key : value (key:是當(dāng)前模塊的路徑 value:是一個(gè)執(zhí)行函數(shù))
接收到modules 里 先定義一個(gè)緩存對(duì)象 installedModules先定一個(gè)緩存目的是如果我當(dāng)前模塊加載完成沒(méi)有必要再進(jìn)行加載
webpack_require 實(shí)現(xiàn)了一個(gè)require方法因?yàn)闉g覽器無(wú)法直接執(zhí)行node的require方法 (詳解如圖)
執(zhí)行__webpack_require__ 發(fā)現(xiàn)接收了一個(gè)入口模塊
終端運(yùn)行: npx webpack , 發(fā)現(xiàn)我們打包當(dāng)前目錄產(chǎn)生了文件夾build目錄
分析了一下打包文件是不是感覺(jué)webpack 源碼沒(méi)有想象的那么難 繼續(xù)我們webpack 的探索之旅。
如何更改webpack 配置文件名稱(chēng)呢其實(shí)很簡(jiǎn)單重命名webpack.config.js (webpack.test.js)
執(zhí)行命令:
npx webpack --config webpack.test.js 發(fā)現(xiàn)可以執(zhí)行webpack打包。
這樣打包我發(fā)現(xiàn)命令很長(zhǎng)所以我們利用packge.json 來(lái)配置打包腳本在scripts-->添加build.
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack --config webpack.config.js" }
終端運(yùn)行 npm run build 發(fā)現(xiàn)執(zhí)行打包結(jié)果一樣.
(2)webpack 其他配 -->置插件的使用不會(huì)生成文件會(huì)生成內(nèi)存中的打包
安裝webpck內(nèi)置服務(wù) webpack-dev-server 好處是
終端執(zhí)行命令: npm i webpack-dev-server -d -save
安裝完成可以執(zhí)行 npx webpack-dev-server 按提示打開(kāi)http://localhost:8080/
如何配置開(kāi)發(fā)服務(wù)運(yùn)行目錄可以在配置文件中添加在webpack.config.js添加devServer
const path = require("path"); module.exports = { mode: "development", //打包模式 entry: "./src/index.js", //入口文件指定 output: { //出口文件配置 配置出口打包路徑 filename: "build.js", //打包的文件名稱(chēng) path: path.resolve(__dirname, "build") //resolve絕對(duì)路徑引入 }, devServer: { //開(kāi)發(fā)服務(wù)器配置 contentBase: "./build", //指向打包目錄 port: 3000, //服務(wù)端口號(hào) progress: true, //打包進(jìn)度 open: true, //是否打開(kāi)瀏覽器 compress: false //是否壓縮 } };
在packge.json中添加start 啟動(dòng)服務(wù)腳本
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack --config webpack.config.js", "start":"webpack-dev-server" }
運(yùn)行 npm run start 發(fā)現(xiàn)沒(méi)有自動(dòng)創(chuàng)建index.html 不能直觀看到我們代碼在瀏覽器的執(zhí)行。
在src目錄下創(chuàng)建html模板 index.html 并安裝 html-webpack-plugin 插件
終端運(yùn)行: 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", //打包的文件名稱(chēng) filename: "build[hash:8] 添加哈希值 path: path.resolve(__dirname, "build") //resolve絕對(duì)路徑引入 }, devServer: { //開(kāi)發(fā)服務(wù)器配置 contentBase: "./build", //指向打包目錄 port: 3000, //服務(wù)端口號(hào) progress: true, //打包進(jìn)度 open: true, //是否打開(kāi)瀏覽器 compress: false //是否壓縮 }, //插件 plugins: [ //數(shù)組形式 存放所有的webpack插件 new HtmlWebPackPlugin({ filename: "index.html", //生成打包文件名 template: "./src/index.html", //模板路徑 minify: { //生產(chǎn)模式可以進(jìn)行配置 removeAttributeQuotes: true, //刪除 html文件雙引號(hào) collapseWhitespace: true //折疊控行 }, hash:true, //添加哈希值 }) ] };
終端執(zhí)行打包測(cè)試:npm run build (build目錄下生成了我們想要生成的index.html文件)
樣式的配置 webpack配置css模塊:配置樣式需要一個(gè)合適loader,loader會(huì)將我們的樣式文件解析成模塊(module)
終端:npm i -d --save css-loader style-loader
如何使用樣式loader進(jìn)行配置呢? 我們先在src下建index.css并給body賦予簡(jiǎn)單樣式
在webpack.config.js 進(jìn)行簡(jiǎn)單配置
css-loader主要解析我們樣式中@import語(yǔ)法,style-loader是吧css樣式插入head標(biāo)簽中.
+ module: { //添加模塊模塊是對(duì)象 rules: [ //規(guī)則 css-loader主要解析我們樣式中@import語(yǔ)法 { test: /.css$/, use: ["style-loader", "css-loader"] //執(zhí)行順序是重右向左執(zhí)行 - >重下到上 } ] }
在index.js中引入樣式文件 import "./index.css"
終端運(yùn)行:npm run start 樣式生效了同樣我們也有對(duì)應(yīng)的less less-loader
終端:npm i -d --save less less-loader
在這里說(shuō)一下loader 的另一種寫(xiě)法對(duì)象寫(xiě)法可以給loader添加一些屬性options
+ module: { //添加模塊模塊是對(duì)象 rules: [ //規(guī)則 css-loader主要解析我們樣式中@import語(yǔ)法 { test: /.css$/, use: [ { loader: "style-loader", options: { insertAt: "top" //把標(biāo)簽插入頂部 } }, "css-loader" ] //執(zhí)行順序是重右向左執(zhí)行 - >重下到上 }, { test: /.less$/, use: [ { loader: "style-loader", options: { insertAt: "top" //把標(biāo)簽插入頂部 } }, "css-loader", "less-loader" ] //執(zhí)行順序是重右向左執(zhí)行 - >重下到上 } ] }
css 樣式的抽離 安裝抽離插件 mini-css-extract-plugin npm i -d --save mini-css-extract-plugin
引入插件并在配置文件中進(jìn)行配置
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", //打包的文件名稱(chēng) filename: "build[hash:8] 添加哈希值 path: path.resolve(__dirname, "build") //resolve絕對(duì)路徑引入 }, devServer: { //開(kāi)發(fā)服務(wù)器配置 contentBase: "./build", //指向打包目錄 port: 3000, //服務(wù)端口號(hào) progress: true, //打包進(jìn)度 open: true, //是否打開(kāi)瀏覽器 compress: false //是否壓縮 }, //插件 plugins: [ //數(shù)組形式 存放所有的webpack插件 new HtmlWebPackPlugin({ filename: "index.html", //生成打包文件名 template: "./src/index.html", //模板路徑 minify: { removeAttributeQuotes: true, //刪除 html文件雙引號(hào) collapseWhitespace: true //折疊控行 }, hash: true //添加哈希值 }), new MinCssExtractPlugin({ filename: "mian.css" }) ], module: { //添加模塊模塊是對(duì)象 rules: [ //規(guī)則 css-loader主要解析我們樣式中@import語(yǔ)法 { test: /.css$/, use: [ MinCssExtractPlugin.loader, //創(chuàng)建link標(biāo)簽放入到main.css里 "css-loader" ] //執(zhí)行順序是重右向左執(zhí)行 - >重下到上 }, { test: /.less$/, use: [ MinCssExtractPlugin.loader, //創(chuàng)建link標(biāo)簽放入到main.css里 "css-loader", "less-loader" ] //執(zhí)行順序是重右向左執(zhí)行 - >重下到上 } ] } }
添加樣式前綴 postcss-loader autoprefixer
npm i postcss-loader autoprefixer -d
module: { //添加模塊模塊是對(duì)象 rules: [ //規(guī)則 css-loader主要解析我們樣式中@import語(yǔ)法 { test: /.css$/, use: [ MinCssExtractPlugin.loader, //創(chuàng)建link標(biāo)簽放入到main.css里 "css-loader", "postcss-loader" ] //執(zhí)行順序是重右向左執(zhí)行 - >重下到上 }, { test: /.less$/, use: [ MinCssExtractPlugin.loader, //創(chuàng)建link標(biāo)簽放入到main.css里 "css-loader", "postcss-loader", "less-loader" ] //執(zhí)行順序是重右向左執(zhí)行 - >重下到上 } ] }
注意 postcss-loader 需要添加一個(gè)配置文件否則不會(huì)生效更目錄創(chuàng)建postcss.config.js
module.exports = { plugins: [require("autoprefixer")] };
但是我們發(fā)現(xiàn)問(wèn)題使用mini-css-extract-plugin插件導(dǎo)致我們css不會(huì)被壓縮。
npm 官網(wǎng)有給出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 插件接下來(lái)我們安裝配置一下.
npm i -d optimize-css-assets-webpack-plugin
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); //壓縮js //配置文件中添加優(yōu)化項(xiàng) optimization: { minimizer: [new OptimizeCSSAssetsPlugin({})] }
使用optimize-css-assets-webpack-plugin我們發(fā)現(xiàn)js右不會(huì)被壓縮 所以要使用uglifyjs-webpack-plugin --save-dev
$ npm install uglifyjs-webpack-plugin --save-dev
配置產(chǎn)考鏈接
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); //壓縮js //配置文件中添加優(yōu)化項(xiàng) optimization: { minimizer: [new OptimizeCSSAssetsPlugin({}),new UglifyJsPlugin()] }語(yǔ)法的轉(zhuǎn)換 babel
在index.js 里寫(xiě)點(diǎn)es6語(yǔ)法箭頭函數(shù)
let fn = () => { console.log("es6 webpack"); }; fn();
終端執(zhí)行: npx webpack 查看打包文件
--我們發(fā)現(xiàn)打包出來(lái)的仍然是es6語(yǔ)法這個(gè)時(shí)候我們需要一個(gè)loader 進(jìn)行轉(zhuǎn)換 babel-loader babel @babel/core
(babel/core是@babel-loader的核心組件轉(zhuǎn)化模塊@babel/preset-env) 參考鏈接
終端運(yùn)行:npm i -d babel-loader babel @babel/core @babel/preset-env
在module添加配置
//在rules下添加配置 { test: /.js$/, use: [ { loader: "babel-loader", options: { //轉(zhuǎn)化es5語(yǔ)法--presets預(yù)設(shè) presets: ["@babel/preset-env"] } } ] },
終端運(yùn)行:npm run build
發(fā)現(xiàn)可以已經(jīng)轉(zhuǎn)換es6語(yǔ)法 但是僅僅這樣不能轉(zhuǎn)換es6高階語(yǔ)法比如一些特殊的類(lèi)函數(shù)
class Test { // new Test() a =1 實(shí)例上添加a屬性 這個(gè)語(yǔ)法屬于es7語(yǔ)法打包時(shí)發(fā)現(xiàn)并不能解析 a = 1; }
終端運(yùn)行:npm run build 發(fā)現(xiàn)報(bào)錯(cuò)提示安裝 @babel/plugin-proposal-class-properties
那我們按照要求按照一下插件 npm i -d @babel/plugin-proposal-class-properties 并進(jìn)行一次配置
//在rules下添加配置 { test: /.js$/, use: [ { loader: "babel-loader", options: { //轉(zhuǎn)化es5語(yǔ)法--presets預(yù)設(shè) presets: ["@babel/preset-env"], plugins: ["@babel/plugin-proposal-class-properties"] } } ] },
還有一種寫(xiě)法 裝飾器@Log打包也是不被解析的 在js 添加
按照錯(cuò)誤提示安裝decorators-legacy 參考鏈接 安裝官方給出配置添加
//在rules下添加配置 { test: /.js$/, use: { { loader: "babel-loader", options: { //轉(zhuǎn)化es5語(yǔ)法--presets預(yù)設(shè) presets: ["@babel/preset-env"], plugins: [ //這里要注意添加順序 ["@babel/plugin-proposal-decorators", { legacy: true }], ["@babel/plugin-proposal-class-properties", { loose: true }]] } } },
轉(zhuǎn)化完語(yǔ)法接下來(lái)看一下babel語(yǔ)法的校驗(yàn) @babel/plugin-transform-runtime @babel/runtime參考鏈接
{ test: /.js$/, use: { loader: "babel-loader", options: { //轉(zhuǎn)化es5語(yǔ)法--presets預(yù)設(shè) 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 實(shí)例方法不被解析 需要一個(gè)補(bǔ)丁模塊@babel/polyfill
npm install --save @babel/polyfill
Babel includes a polyfill that includes a custom regenerator runtime and core-js.
使用可以直接在js 里引入即可。
接下來(lái)看一下代碼校驗(yàn)ESLint代碼校驗(yàn)工具參考鏈接
終端安裝 npm i -d eslint eslint-loader
根據(jù)項(xiàng)目需求下載對(duì)應(yīng)的eslintrc.json 下載鏈接
//代碼校驗(yàn)eslint { test: /.js$/, use: { loader: "eslint-loader", options: { enforce: "pre" //強(qiáng)制執(zhí)行順序 } } },
DEMO
本文回顧 1、webpack基本功能 build.js 打包的原理及源碼分析 2、webpack基礎(chǔ)配置及常用插件配置安裝 3、loader的使用與配置樣式的處理 4、webpack優(yōu)化項(xiàng)的簡(jiǎn)單使用 5、babel語(yǔ)法轉(zhuǎn)換與使用 babel語(yǔ)法校驗(yàn) . 完成以上我相信大家可以掌握并搭建簡(jiǎn)單webpack項(xiàng)目。
第二章我們將講解webpack 其他組件的配置及webpack優(yōu)化項(xiàng) webpack圖片處理 多入口應(yīng)用)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109700.html
摘要:同時(shí)它還提供了自動(dòng)刷新熱更新等功能,使開(kāi)發(fā)變得非常方便。的到來(lái)減少了很多的配置,它內(nèi)置了很多的功能。 上一篇文章里詳細(xì)介紹了一下插件的用法,這一篇文章接著豐富module.exports里的屬性。如今的前端發(fā)展已經(jīng)非常迅速了,伴隨而來(lái)的是開(kāi)發(fā)模式的轉(zhuǎn)變?,F(xiàn)在已經(jīng)不再是寫(xiě)個(gè)靜態(tài)頁(yè)面并放在瀏覽器里打開(kāi)預(yù)覽一下了。在實(shí)際的開(kāi)發(fā)中會(huì)經(jīng)常需要使用http服務(wù)器,比如之前的ajax,想要看到效果就...
摘要:處理與的語(yǔ)法大部分已經(jīng)被各在瀏覽器所支持,當(dāng)然除了萬(wàn)惡的,但是部分新增很遺憾并不被瀏覽器所支持比如內(nèi)置對(duì)象新增的一些方法和對(duì)象等。但是在這里卻不需要,是因?yàn)榈睦镆呀?jīng)把內(nèi)容添上了,就不需要?jiǎng)?chuàng)建文件了源碼下載下一篇從入門(mén)到精通第三方庫(kù)六 通過(guò)上一篇文章相信大家已經(jīng)明白了loader的概念。那這篇文章繼續(xù)介紹一些常用loader,并展現(xiàn)它的強(qiáng)大之處 處理less less與sass的功能都一...
摘要:這就需要把文件單獨(dú)拎出來(lái),那需要一個(gè)插件來(lái)配合才能完成版本需要以上,低版本請(qǐng)使用使用步驟安裝在里引入模塊寫(xiě)入陳學(xué)輝文件目錄會(huì)放入里寫(xiě)入代替執(zhí)行命令后可以看到目錄里已經(jīng)多了一個(gè)文件夾,這個(gè)文件夾里放了一個(gè)文件。 概念 在webpack中任何一個(gè)東西都稱(chēng)為模塊,js就不用說(shuō)了。一個(gè)css文件,一張圖片、一個(gè)less文件都是一個(gè)模塊,都能用導(dǎo)入模塊的語(yǔ)法(commonjs的require,E...
摘要:在開(kāi)發(fā)的時(shí)候會(huì)時(shí)常用到第三方的庫(kù)或者框架,比如耳熟能詳?shù)摹J褂玫谌綆?kù)在入口文件當(dāng)中直接導(dǎo)入安裝目錄結(jié)構(gòu)如圖內(nèi)容如下內(nèi)容如下陳學(xué)輝內(nèi)容如下這是自帶的內(nèi)容如下內(nèi)容如下引入后打開(kāi)頁(yè)面會(huì)看到最后一個(gè)標(biāo)簽有了一個(gè)綠色的背景。 在開(kāi)發(fā)的時(shí)候會(huì)時(shí)常用到第三方的庫(kù)或者框架,比如耳熟能詳?shù)膉query。借助它們能提高開(kāi)發(fā)效率,但是如何在webpack中使用呢。這篇文章介紹兩個(gè)東西,如何使用第三方庫(kù)以及...
前言 什么是webpack 本質(zhì)上,webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)遞歸地構(gòu)建一個(gè)依賴(lài)關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個(gè)模塊,然后將所有這些模塊打包成一個(gè)或多個(gè) bundle。 webpack 有哪些功能(代碼轉(zhuǎn)換 文件優(yōu)化 代碼分割 模塊合并 ...
閱讀 3576·2021-11-16 11:45
閱讀 2149·2021-11-08 13:23
閱讀 2228·2021-10-11 10:59
閱讀 2904·2021-09-27 13:36
閱讀 2492·2019-08-30 15:54
閱讀 2684·2019-08-29 16:58
閱讀 2801·2019-08-29 16:56
閱讀 1351·2019-08-26 13:52