爲本身瞭解
webpack的過程作一個總結,也但願對想要了解的小夥伴有所幫助。javascript
既然是學習瞭解webpack
,那我假定你瞭解npm和node.js了
。css
先對核心概念有個大概的瞭解,不理解也不要緊,看完後面的例子應該會有必定的認識。html
- Entry:入口,Webpack 執行構建的第一步將從 Entry 開始,可抽象成輸入。
- Module:模塊,在 Webpack 裏一切皆模塊,一個模塊對應着一個文件。Webpack 會從配置的 Entry 開- 始遞歸找出全部依賴的模塊。
- Chunk:代碼塊,一個 Chunk 由多個模塊組合而成,用於代碼合併與分割。
- Loader:模塊轉換器,用於把模塊原內容按照需求轉換成新內容。
- Plugin:擴展插件,在 Webpack 構建流程中的特定時機注入擴展邏輯來改變構建結果或作你想要的事情。
- Output:輸出結果,在 Webpack 通過一系列處理並得出最終想要的代碼後輸出結果。
1.新建一個工程目錄study_webpack
(用於嘗試各類例子)
2.全局安裝webpack(爲了方便用命令,安裝的版本看下面的文件)vue
cnpm install -g webpack cnpm install -g webpack-cli
tip:考慮到後續的一些插件的版本問題,放出個人package.jsonjava
{ "name": "webpack-study-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": {}, "keywords": [], "author": "", "license": "MIT", "devDependencies": { "css-loader": "^1.0.1", "html-webpack-plugin": "^3.2.0", "vue-loader": "^15.4.2", "vue-template-compiler": "^2.5.17", "webpack": "^4.25.1", "webpack-cli": "^3.1.2" }, "dependencies": { "vue": "^2.5.17" } }
基本栗子演示單個入口
webpack打包結果,後續例子無特殊說明均採用該目錄結構node
在demo1目錄下準備調用文件dist/index.html
webpack
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <!-- 引入打包的文件 --> <script src="./bundle.js"></script> </body> </html>
入口文件index.js
web
document.write("<h1>Hello World</h1>");
webpack配置webpack.config.js
shell
const path=require('path'); module.exports = { entry: "./index.js", output: { filename: "bundle.js", path:path.resolve(__dirname,"./") } };
在終端中執行webpack
命令(webpack.config.js
所在的目錄)npm
tip:webpack默認讀取目錄下的webpack.config.js的配置文件。
執行結果
Hash: 7a488a408fbb07bfacd8 Version: webpack 4.25.1 Time: 273ms Built at: 2018-11-11 16:19:40 Asset Size Chunks Chunk Names bundle.js 968 bytes 0 [emitted] main Entrypoint main = bundle.js [0] ./index.js 40 bytes {0} [built] WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
第一個webpack的例子成功了,是否是很簡單,立刻就能夠成爲webpack配置工程師了,想一想還有些小激動。
每每一個應用不單單隻有一個入口(第三方庫啦,多個頁面啦,等等)
在demo2目錄下面寫調用文件dist/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script src="./bundle1.js"></script> <script src="./bundle2.js"></script> </body> </html>
而後是入口文件module1.js
和module2.js
document.write("<h1>Hello Module1</h1>");
document.write("<h1>Hello Module2</h1>");
打包結果執行結果
Webpack 把一切文件看做模塊,要支持非 JavaScript 類型的文件,須要使用 Webpack 的 Loader機制
target:編譯.vue文件
準備工做:
cnpm i vue --save cnpm i vue-loader --save-dev cnpm i css-loader --save-dev cnpm i vue-template-compiler --save-dev
新建demo03目錄,調用文件dist/index.html
。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"></div> <script src="./bundle.js"></script> </body> </html>
入口文件index.js
import Vue from "vue"; import App from "./index.vue"; /* eslint-disable no-new */ new Vue({ el: "#app", template: "<App/>", components: { App } });
index.vue
文件
<template> <div id="app"> {{msg}} </div> </template> <script> export default { name: "app", data: function() { return { msg:"hello loader" }; } }; </script> <style> </style>
最後是配置文件webpack.config.js
const VueLoaderPlugin = require("vue-loader/lib/plugin"); module.exports={ entry:"./index.js", output:{ filename:"bundle.js" }, resolve: { alias: { vue$: "vue/dist/vue.js" // 設置別名,找到node_modules下的vue }, extensions: [".js", ".json",".vue"] // 支持.vue擴展 }, module:{ rules:[ { test:/\.vue$/, loader:"vue-loader" // 添加vue-loader } ] }, plugins:[ new VueLoaderPlugin() // vue-loader須要添加插件配置 ] }
相比前面的例子拋開其中的優化配置(別名之類的)
,實際上添加了一個module.rules選項,這個選項的做用專門用來配置loader,其中test
字段經過正則匹配模塊
擴展名,告訴webpack對非javascript
模塊應用什麼loader。
多個loader的例子容我省略,你(我)辣(偷)麼(個)機(懶)智
Plugin 是用來擴展 Webpack 功能的,經過在構建流程裏注入鉤子實現,它給 Webpack 帶來了很大的靈活性
因此,綜上所述,plugins
就是用來擴展webpack的,好比工做流(代碼壓縮),提升開發效率(熱重載,靜態服務器)
等。
ps:其實上一個例子有plugins配置,不過那是vue-loader須要
target:動態生成html
前面的例子,咱們的調用的html都是預先生成的,實際開發中幾十個頁面打包一次純手動成本過高,咱們以html-webpack-plugin
插件爲例
入口文件index.js
var name1="hello"; var name2="plugins"; document.write(`<h1>${name1} ${name2}</h1>`);
配置文件webpack.config.js
先安裝插件
cnpm i html-webpack-plugin --save-dev
var HtmlWebpackPlugin = require("html-webpack-plugin"); var path = require("path"); module.exports = { entry: "./index.js", output: { path: path.resolve(__dirname, "./dist"), filename: "bundle.js" }, plugins: [new HtmlWebpackPlugin({ // 在插件數組裏面加一個插件就行了,是否是so easy title:"demo04 title", template:"./template.html", inject:true })] };
tip:該插件咱們配置一個html模板
模板文件template.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> </body> </html>
想一想幾十個頁面經過一個模板生成是否是效率會高上很多呢
未完待續,沒寫多少頁面卡的不行