webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler),當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundle
javascript
使用Webpack做爲前端構建工具:html
在webpack
應用中有兩個核心:前端
├── src # 源碼目錄 │ ├── a-module.js │ └── index.js
編寫 a-module.jsjava
module.exports = 'hello';
編寫 index.jsnode
let a = require('./a-module'); console.log(a);
這裏咱們使用
CommonJS
模塊的方式引入,這種方式默認在瀏覽器上是沒法運行的,咱們但願經過webpack
來進行打包!jquery
npm init -y npm install webpack webpack-cli --save-dev
webpack
默認支持0配置,配置scripts
腳本webpack
"scripts": { "build": "webpack" }
執行npm run build
,默認會調用 node_modules/.bin
下的webpack
命令,內部會調用webpack-cli
解析用戶參數進行打包。默認會以 src/index.js
做爲入口文件。web
這裏也可使用
npx webpack
,npx
是 5.2版本以後npm
提供的命令能夠執行.bin
下的可執行文件npm
咱們能夠發現已經產生了dist
目錄,此目錄爲最終打包出的結果。main.js
能夠在html中直接引用,這裏還提示咱們默認mode
爲production
json
咱們打包時通常不會採用0配置,webpack
在打包時默認會查找當前目錄下的 webpack.config.js or webpackfile.js
文件。
經過配置文件進行打包
const path = require('path'); module.exports = { entry:'./src/index.js', output:{ filename:'bundle.js', // 打包出的結果文件 path:path.resolve(__dirname,'dist') // 打包到dist目錄下 } }
咱們須要在打包時提供mode
屬性來區分是開發環境仍是生產環境,來實現配置文件的拆分
├── build │ ├── webpack.base.js │ ├── webpack.dev.js │ └── webpack.prod.js
咱們能夠經過指定不一樣的文件來進行打包
配置scripts
腳本
"scripts": { "build": "webpack --config ./build/webpack.prod", "dev": "webpack --config ./build/webpack.dev" }
能夠經過 config
參數指定,使用哪一個配置文件來進行打包
經過env參數區分
"scripts": { "build": "webpack --env.production --config ./build/webpack.base", "dev": "webpack --env.development --config ./build/webpack.base" }
改造webpack.base
文件默認導出函數,會將環境變量傳入到函數的參數中
module.exports = (env)=>{ console.log(env); // { development: true } }
合併配置文件
咱們能夠判斷當前環境是不是開發環境來加載不一樣的配置,這裏咱們須要作配置合併
安裝webpack-merge
:
npm install webpack-merge --save-dev
webpack.dev
配置
module.exports = { mode:'development' }
webpack.prod
配置
module.exports = { mode:'production' }
webpack.base
配置
const path = require('path'); const merge = require('webpack-merge'); // 開發環境 const dev = require('./webpack.dev'); // 生產環境 const prod = require('./webpack.prod'); const base = { // 基礎配置 entry:'./src/index.js', output:{ filename:'bundle.js', path:path.resolve(__dirname,'../dist') } } module.exports = (env) =>{ if(env.development){ return merge(base,dev); }else{ return merge(base,prod) } }
後續的開發中,咱們會將公共的邏輯放到base
中,開發和生產對的配置也分別進行存放!
配置開發服務器,能夠在實如今內存中打包,而且自動啓動服務
npm install webpack-dev-server --save-dev
"scripts": { "build": "webpack --env.production --config ./build/webpack.base", "dev": "webpack-dev-server --env.development --config ./build/webpack.base" }
經過執行npm run dev
來啓啓動開發環境
默認會在當前根目錄下啓動服務
配置開發服務的配置
const path = require('path') module.exports = { mode:'development', devServer:{ // 更改靜態文件目錄位置 contentBase:path.resolve(__dirname,'../dist'), compress:true, // 開啓gzip port:3000, // 更改端口號 } }
自動產生html,並引入打包後的文件
編輯webpack.base
文件
const HtmlWebpackPlugin = require('html-webpack-plugin'); plugins:[ new HtmlWebpackPlugin({ filename:'index.html', // 打包出來的文件名 template:path.resolve(__dirname,'../public/index.html'), hash:true, // 在引用資源的後面增長hash戳 minify:{ removeAttributeQuotes:true // 刪除屬性雙引號 } }) ]
根據不一樣入口 生成多個js文件,引入到不一樣html中
── src ├── entry-1.js └── entry-2.js
多入口須要配置多個entry
entry:{ jquery:['jquery'], // 打包jquery entry1:path.resolve(__dirname,'../src/entry-1.js'), entry2:path.resolve(__dirname,'../src/entry-2.js') }, output:{ filename:'[name].js', path:path.resolve(__dirname,'../dist') },
產生多個Html文件
new HtmlWebpackPlugin({ filename:'index.html', template:path.resolve(__dirname,'../public/template.html'), hash:true, minify:{ removeAttributeQuotes:true }, chunks:['jquery','entry1'], // 引入的chunk 有jquery,entry }), new HtmlWebpackPlugin({ filename:'login.html', template:path.resolve(__dirname,'../public/template.html'), hash:true, minify:{ removeAttributeQuotes:true }, inject:false, // inject 爲false表示不注入js文件 chunksSortMode:'manual', // 手動配置代碼塊順序 chunks:['entry2','jquery'] })
以上的方式不是很優雅,每次都須要手動添加HtmlPlugin
應該動態產生html
文件,像這樣:
let htmlPlugins = [ { entry: "entry1", html: "index.html" }, { entry: "entry2", html: "login.html" } ].map( item => new HtmlWebpackPlugin({ filename: item.html, template: path.resolve(__dirname, "../public/template.html"), hash: true, minify: { removeAttributeQuotes: true }, chunks: ["jquery", item.entry] }) ); plugins: [...htmlPlugins]
可使用clean-webpack-plugin
手動清除某個文件夾內容:
安裝
npm install --save-dev clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); new CleanWebpackPlugin({ // 清空匹配的路徑 cleanOnceBeforeBuildPatterns: [path.resolve('xxxx/*'),'**/*'], })
這樣就能夠清空指定的目錄了,咱們能夠看到webpack
插件的基本用法就是 new Plugin
而且放到plugins
中