webpack 專題
● 什麼是 webpack
解決 模塊之間的依賴;把 各個模塊 按照特定的規則 組織在一起, 最終幫助我們合併 打包成一個 js 文件;
這個過程 一般叫做 模塊打包
它的本質是:分析你的項目結構,找到 js 模塊 之間的依賴關係,以及一些 拓展語言比如 :"scss" "less" "ES6" "ts" 等等. 幫助我們 用 node 處理解析成 我們瀏覽器 能夠 識別 運行的 語言
- 有類似 功能的: glup, rollup, 目前最流行的 就是 webpack ; rollup 發展也是十分迅猛; 是vue 源碼的打包方式
● 爲什麼要用 webpack
可以 爲我們 提供一些 很多便利;
- 預處理 一些文; 比如 "scss" "css"
- 自動處理 web css3 屬性前綴 兼容性
- 單文件 多文件打包
- 有完整的代碼 分割 解決方案
- 模塊化開發(import require) 支持多種模塊化 標準
- 壓縮 JS 代碼
- 按需加載 等等
一般像 Vue 或者 React 等等的 框架 都可以 用腳手架 直接創建項目, 項目的配置文件也都可以 自動生成 包括webpack!
在這裏我們就 手動的生成下 項目的 webpack
- 創建一個文件 webpackdemo
- 運行 npm init (填寫一些必要參數 一路回車) 完畢之後可以看到一個 package.json 文件
- 運行 npm install webpack --save (安裝 webpack)
- 運行 npm install webpack-cli --save (安裝 wepack-cli)
- 創建一個 名爲 src 的文件夾 創建一個 index.js 文件(默認入口文件) 然後 命令行 webpack 就能 利用 默認配置屬性打包; 會自動 生成一個 dist 的文件夾
自定義 webpack 配置文件:
在 項目的根目錄創建一個 叫 build 的文件夾, 接着創建一個 webpack.config.js 文件; 這個就是webpack 的配置文
然後 運行 一條命令: webpack --config build/webpack.config.js --mode development
就能按照我們 的配置 進行 打包了
但是每次都 打一行這樣的代碼 很麻煩: 所以呢 我們修改 package.json 文件 添加兩行代碼
然後命令行 換成:npm run build 就能實現打包了哈
爲在開發階段 方便查看: npm install webpack-dev-server --dev ; 這樣只要我們編寫的 腳本有修改;瀏覽器就能及時的刷新我們修改的內容;
我們當然也可以把 webpack-dev-server 添加到啓動配置裏面
webpack 多文件 & 動態文件的打包:
單文件 & 多文件 打包:
打包之後 輸出的文件名稱; 可以添加 hash 防止cdn 或者客戶端 緩存
- hash : 整個項目 打包的 hash
- chunkhash : 對應模塊 或者 腳本的 hash
可配置 多文件打包插件
當有更多 腳本的時候;不可能手動挨個 添加了;這個時候 就需要用到插件了:
● npm install glob --dev
var webpack = require('webpack')
var path = require('path')
var glob = require('glob')
var ENTRY_PATH = path.resolve(__dirname, '../src/index.js')
var DIST_PATH = path.resolve(__dirname, '../dist')
var SRC_PATH = path.resolve(__dirname, '../src')
var entryFiles = {};
// var files = glob.sync(SRC_PATH + '**/*.js')
// var files1 = path.join(SRC_PATH, '**/*.js')
// console.log("files1:", files1)
// console.log("files:", files)
var files = glob.sync(path.join(SRC_PATH, '/**/*.js'));
files.forEach(function(file, index) {
var subKey = file.match(/src\/(\S*)\.js/)[1];
entryFiles[subKey] = file
})
console.log("entryFiles:", entryFiles)
module.exports = {
//入口 js 文件
// entry: ENTRY_PATH, 方式1 單文件
// entry:[SRC_PATH+'/index.js',SRC_PATH+'/test.js'], 方式2 多文件
// entry: { // 方式3 多文件
// index: SRC_PATH + '/index.js',
// test: SRC_PATH + '/test.js'
// },
entry: entryFiles, // 方式4 glob 插件集成
//編譯輸入文件路徑
output: {
path: DIST_PATH,
//filename: 'index.js'
//filename: '[name]_[hash].js'
//filename: '[name]_[chunkhash].js' //32 位長度 hash
filename: '[name]_[chunkhash:5].js' //限制 hash 字符串長度 5
},
//模塊解析配置
module: {},
//模塊插件
plugins: [],
//開發服務器
devServer: {
host: '0.0.0.0',
port: 8071, // 服務器端口
hot: true, //熱刷新
contenBase: DIST_PATH, // 熱刷新文件路徑
histroyApiFallback: true, //找不到的文件 都跳轉到 contenBase 路徑
open: true, //是否啓動完畢打開瀏覽器
useLocalIp: true, //是否使用自己 ip 打開
https: true, //開啓 https
proxy: { //開啓代理的配置
'/api': 'http://localhost:3000'
}
}
}
編譯 webpack 中的 html 文件
使用的是 html-webpack-plugin
首先你得安裝 npm install html-webpack-plugin --dev
手動添加 html
var webpack = require('webpack')
var path = require('path')
var glob = require('glob')
var htmlwebpackplugin = require('html-webpack-plugin')
var ENTRY_PATH = path.resolve(__dirname, '../src/index.js')
var DIST_PATH = path.resolve(__dirname, '../dist')
var SRC_PATH = path.resolve(__dirname, '../src')
var entryFiles = {};
// var files = glob.sync(SRC_PATH + '**/*.js')
// var files1 = path.join(SRC_PATH, '**/*.js')
// console.log("files1:", files1)
// console.log("files:", files)
var files = glob.sync(path.join(SRC_PATH, '/**/*.js'));
files.forEach(function(file, index) {
var subKey = file.match(/src\/(\S*)\.js/)[1];
entryFiles[subKey] = file
})
console.log("entryFiles:", entryFiles)
module.exports = {
//入口 js 文件
// entry: ENTRY_PATH, 方式1 單文件
// entry:[SRC_PATH+'/index.js',SRC_PATH+'/test.js'], 方式2 多文件
// entry: { // 方式3 多文件
// index: SRC_PATH + '/index.js',
// test: SRC_PATH + '/test.js'
// },
entry: entryFiles, // 方式4 glob 插件集成
//編譯輸入文件路徑
output: {
path: DIST_PATH,
//filename: 'index.js'
//filename: '[name]_[hash].js'
//filename: '[name]_[chunkhash].js' //32 位長度 hash
filename: '[name]_[chunkhash:5].js' //限制 hash 字符串長度 5
},
//模塊解析配置
module: {},
//模塊插件
plugins: [
new htmlwebpackplugin({
filename: DIST_PATH + '/index.html',
title: '測試',
template: path.resolve(__dirname, '../index.html'),
inject: true, //body (body 底部位置) head (head 底部位置) true false(不插入 js 文件) 講 js 文件插入到 html 的位置:
hash: true,
chunks: ['index', 'name'] //需要引入的 js文件 沒有說明的話 則是 全部引入
// minify:true //是否壓縮
}),
new htmlwebpackplugin({
filename: DIST_PATH + '/sub/subindex.html',
title: '測試2',
template: SRC_PATH + '/sub/subindex.html',
inject: true, //body (body 底部位置) head (head 底部位置) true false(不插入 js 文件) 講 js 文件插入到 html 的位置:
hash: true,
chunks: ['test']
// minify:true //是否壓縮
})
],
//開發服務器
devServer: {
host: '0.0.0.0',
port: 8071, // 服務器端口
hot: true, //熱刷新
contenBase: DIST_PATH, // 熱刷新文件路徑
histroyApiFallback: true, //找不到的文件 都跳轉到 contenBase 路徑
open: true, //是否啓動完畢打開瀏覽器
useLocalIp: true, //是否使用自己 ip 打開
https: true, //開啓 https
proxy: { //開啓代理的配置
'/api': 'http://localhost:3000'
}
}
}
代碼遍歷添加 多 html
和上面一樣 使用 glob 插件來遍歷文件夾
var webpack = require('webpack')
var path = require('path')
var glob = require('glob')
var htmlwebpackplugin = require('html-webpack-plugin')
var ENTRY_PATH = path.resolve(__dirname, '../src/index.js')
var DIST_PATH = path.resolve(__dirname, '../dist')
var SRC_PATH = path.resolve(__dirname, '../src')
var entryFiles = {};
// var files = glob.sync(SRC_PATH + '**/*.js')
// var files1 = path.join(SRC_PATH, '**/*.js')
// console.log("files1:", files1)
// console.log("files:", files)
var files = glob.sync(path.join(SRC_PATH, '/**/*.js'));
files.forEach(function(file, index) {
var subKey = file.match(/src\/(\S*)\.js/)[1];
entryFiles[subKey] = file
})
console.log("entryFiles:", entryFiles)
var pluginAll = [] //放所有的插件
var pages = glob.sync(path.join(SRC_PATH, '/**/*.html'));
console.log("----pages:", pages)
pages.forEach(function(page, index) {
var pageName = page.match(/src\/(\S*)\.html/)[1];
// console.log("pageName:", pageName)
pluginAll.push(new htmlwebpackplugin({
filename: DIST_PATH + '/' + pageName + '.html',
title: '測試' + pageName,
template: path.resolve(__dirname, '../index.html'),
inject: true, //body (body 底部位置) head (head 底部位置) true false(不插入 js 文件) 講 js 文件插入到 html 的位置:
hash: true,
chunks: ['index', 'name'] //需要引入的 js文件 沒有說明的話 則是 全部引入
// minify:true //是否壓縮
}), )
})
module.exports = {
//入口 js 文件
// entry: ENTRY_PATH, 方式1 單文件
// entry:[SRC_PATH+'/index.js',SRC_PATH+'/test.js'], 方式2 多文件
// entry: { // 方式3 多文件
// index: SRC_PATH + '/index.js',
// test: SRC_PATH + '/test.js'
// },
entry: entryFiles, // 方式4 glob 插件集成
//編譯輸入文件路徑
output: {
path: DIST_PATH,
//filename: 'index.js'
//filename: '[name]_[hash].js'
//filename: '[name]_[chunkhash].js' //32 位長度 hash
filename: '[name]_[chunkhash:5].js' //限制 hash 字符串長度 5
},
//模塊解析配置
module: {},
//模塊插件
// plugins: [
// new htmlwebpackplugin({
// filename: DIST_PATH + '/index.html',
// title: '測試',
// template: path.resolve(__dirname, '../index.html'),
// inject: true, //body (body 底部位置) head (head 底部位置) true false(不插入 js 文件) 講 js 文件插入到 html 的位置:
// hash: true,
// chunks: ['index', 'name'] //需要引入的 js文件 沒有說明的話 則是 全部引入
// // minify:true //是否壓縮
// }),
// new htmlwebpackplugin({
// filename: DIST_PATH + '/sub/subindex.html',
// title: '測試2',
// template: SRC_PATH + '/sub/subindex.html',
// inject: true, //body (body 底部位置) head (head 底部位置) true false(不插入 js 文件) 講 js 文件插入到 html 的位置:
// hash: true,
// chunks: ['test']
// // minify:true //是否壓縮
// })
// ],
plugins: pluginAll,
//開發服務器
devServer: {
host: '0.0.0.0',
port: 8071, // 服務器端口
hot: true, //熱刷新
contenBase: DIST_PATH, // 熱刷新文件路徑
histroyApiFallback: true, //找不到的文件 都跳轉到 contenBase 路徑
open: true, //是否啓動完畢打開瀏覽器
useLocalIp: true, //是否使用自己 ip 打開
https: true, //開啓 https
proxy: { //開啓代理的配置
'/api': 'http://localhost:3000'
}
}
}