Webpack 4.X
文章目录
一、Webpack概述
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
1.1 Webpack的功能
- 代码转换:将ES6转换成ES5的JavaScript语言,把Less转换成Sass
- 文件优化:压缩代码的体积,合并文件
- 代码分隔:公共页面的抽离
- 模块合并:多个模块合并为一个模块
- 自动刷新:启动一个本地服务器,实现代码和模块的热更新
- 代码校验:校验代码是否符合规范标准
- 自动发布:将完成打包后的文件自动发布到服务器上
二、Webpack的基本构成
- 入口:entry
- 出口:output
- 插件:plugins
- 转化器:loaders
- 开发服务器:devServer
三、Webpack的安装
3.1 全局安装
NPM方式全局安装Webpack以及webpack-cli
npm install webpack webpack-cli -g
YAEN方式全局安装Webpack以及webpack-cli
yarn add webpack webpack-cli -g
3.2 局部安装
初始化环境,配置package.json文件
npm init -y
本地安装开发环境webpack以及webpack-cli包,生成node_modules
npm webpack webpack-cli -D
devDependencies: ,编写代码阶段,用于开发环境
dependencies: 代码被压缩,发布到生产环境-g: 全局环境安装
-y: 表示 “yes”,省略确认步骤,生成默认的配置文件
-D: 表示 “-save-dev”,写入开发环境
-S: 表示 “-save”,写入生产环境
@: 定义webpack版本号 例 webpack@4.1.0
3.3 初步配置文件
目录分布
package.json配置文件
{
"name": "webpack4.x",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.1.0"
}
}
webpack.config.js配置文件
const path = require('path');
module.exports = {
// 入口配置
entry:{
entryName:'./src/index.js'
},
// 出口配置
output:{
path:path.resolve(__dirname,'dist'),
filename:'bundle.js'
}
};
生成dist目录
webpack
按照webpack.config.js的配置对文件打包成dist目录
四、多入口多出口-entry&output
4.1 入口-entry
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
默认值是 ./src/index.js
但你可以通过在 webpack configuration中配置 entry 属性,来指定一个(或多个)不同的入口起点。是指在webpack.config.js配置文件中entyr设置多个入口地址和在output设置多个出口地址。
4.2 出口-output
output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js
,其他生成文件默认放置在 ./dist
文件夹中。
4.3 依赖包安装
- 导入html-webpack-plugin依赖包
npm install html-webpack-plugin -D
html-webpack-plugin 插件生成 HTML5的index.html页面,当有多入口时,将入口文件自动使用script标签引入
- 导入clean-webpack-plugin依赖包
npm install clean-webpack-plugin -D
clean-webpack-plugin插件用于删除/清理已经构建的文件夹
4.3.1 html-webpack-plugin配置表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cw5jG9kH-1588677251263)(Webpack.assets/html-webpack-plugin.png)]
详细配置的使用方式参照网址:
4.4 多入口对应单出口
webpack.config.js配置文件
/*jshint esversion:6*/
// 导入path
const path = require('path');
// 导入html-webpack-plugin
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 设置生产模式
mode:'development',
// 入口配置
entry:{
indexOne:'./src/indexOne.js',
indexTwo:'./src/indexTwo.js'
},
// 出口配置
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].bundle.js'// 多出口的bundle.js写法
},
plugins:[
new htmlWebpackPlugin({
// 设置模板
template:'./src/index.html',
// 设置标题
title:'Webpack Learning',
// 消除生成链接的缓存,使用随机哈希码为为后缀
hash:true
})
]
};
src目录下的 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h3>Webpack学习</h3>
<div id="container">
<div>
<span id="showText1"></span>
<span id="showTest2"></span>
</div>
</div>
</body>
</html>
title 的使用,配合对应的HTML文件,对title标签内语句声明:
<%= htmlWebpackPlugin.options.title%>
dist目录下的 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack Learning</title>
</head>
<body>
<h3>Webpack学习</h3>
<div id="container">
<div>
<span id="showText1"></span>
<span id="showTest2"></span>
</div>
</div>
<script src="indexOne.bundle.js?5a081682f2f6abb0c542"></script>
<script src="indexTwo.bundle.js?5a081682f2f6abb0c542"></script>
</body>
</html>
4.5 多入口对应多出口
webpack.config.js配置文件
const path = require('path');// 导入path
const HtmlWebpackPlugin = require('html-webpack-plugin');// 导入html-webpack-plugin
const {CleanWebpackPlugin} = require('clean-webpack-plugin');// 导入clean-webpack-plugin
module.exports = {
// 设置生产模式
mode:'development',
// 入口配置
entry:{
One:'./src/webpack_EntryOutput/One.js',
Two:'./src/webpack_EntryOutput/Two.js'
},
// 出口配置
output:{
filename:'[name].js',// 多出口的.js写法
path:path.resolve(__dirname,'dist/webpack_EntryOutput')
},
// 插件配置
plugins:[
// 每次进行webpack命令后,删除旧dist目录
new CleanWebpackPlugin(),
// 生成第一个页面
new HtmlWebpackPlugin({
filename:'firstPage.html',//为生成的出口文件设置名字,默认为index.html
chunks:['One'],// 设置指定引入的模块
template:'./src/webpack_EntryOutput/indexOld.html',// 设置模板
title:'First page',// 设置标题
hash:true // 消除生成链接的缓存,使用随机哈希码为最为后缀
}),
// 生成第二个页面
new HtmlWebpackPlugin({
filename:'SecondPage.html',
chunks:['Two'],
template:'./src/webpack_EntryOutput/indexNew.html',
title:'Second page',
hash:true
}),
]
};
src目录下的 indexOld.html和indexNew.html
- indexOld.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h3>Webpack学习</h3>
<div id="container">
<div>
<span id="showText1"></span>
</div>
</div>
</body>
</html>
- indexNew.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h3>Webpack学习</h3>
<div id="container">
<div>
<span id="showText2"></span>
<div id="class"></div>
</div>
</div>
</body>
</html>
dist目录下的 firstPage.html和secondPage.html
- firstPage.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First page</title>
</head>
<body>
<h3>Webpack学习</h3>
<div id="container">
<div>
<span id="showText1"></span>
</div>
</div>
<script src="One.bundle.js?4b3ddb68e68a51656ea5"></script></body>
</html>
- secondPage.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Second page</title>
</head>
<body>
<h3>Webpack学习</h3>
<div id="container">
<div>
<span id="showText2"></span>
<div id="class"></div>
</div>
</div>
<script src="Two.bundle.js?4b3ddb68e68a51656ea5"></script></body>
</html>
五、开发服务器-devServer
webpack-dev-server 是在devServer里运行的插件,用于本地开发的工具,它支持代码热更新和模块组件热更新,能迅速将更改后的代码和模块更新到浏览器中。热更新的功能适用于开发模式之中,让用户开发更迅速便捷,而不适用于生产环境。
- 导入webpack-dev-server依赖包
npm install webpack-dev-server -D
- 配置webpack.config.js文件的devServer项
module.exports = {
devServer:{
// 设置服务器基本的访问目录
contentBase: paht.resolve(__dirname,'dist'),
host: 'localhost', // 服务器IP地址
port: 8089, // 设置端口
open: true // 自动打开页面
hot:true // 开启热更新功能
}
}
- 配置webpack.config.js文件的plugins项
const webpack = require('webpack'); //引入webpack
module.exports = {
plugins:{
new webpack.HotModuleReplacementPlugin() //配合dveServer的Hot开启热更新
}
}
- 配置package.json文件的scripts项
"scripts": {
"dev": "webpack-dev-server"
}
- 运行webpack-dev-server
npm run dev
- 浏览器输入对应的IP地址和端口号,默认进入index.html页面
http://loclahost:8089
六、加载器-Loader
webpack 只能理解 JavaScript 和 JSON 文件。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
6.1 CSS文件的加载与提取分离
6.1.1 CSS文件加载到JS文件中
- 创建style.css文件
body{
background: #cccccc
}
- 创建index.js文件
import '../css/style.css'; // index.js文件里导入css路径
document.write('----输出到页面的文字----');
- 安装style-loader与css-loader依赖包
npm install style-loader css-loader -D
- 在weboack.config.js文件配置module的rules规则
module: {
rules: [
{
test: /\.css$/, //正则判断寻找.css文件
loader: ['style-loader','css-loader']
}
],
}
loader 的三种书写方式:
loader: [ ‘style-loader’,‘css-loader’ ]
use: [ ‘style-loader’,‘css-loader’ ]
use: [
{loader: ‘style-loader’},
{loader: ‘cssloader’}
]
- 配置package.jsom文件
{
"scripts":{
"dev":"webpack-dev-server --mode development"
}
}
- 开启开发服务器devServer查看
npm run dev
6.1.2 CSS文件的提取分离
- 安装extract-text-webpack-plugin依赖包
npm i extract-text-webpack-plugin -D
- webpack.config.js配置
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules:[
test:/\.css$/,
use:ExtractTextWebpackPlugin.extract({
fallback:'style-loader', // 回滚函数
use:'css-loader',
publicPath:'../' //css文件为找图片设置静态路径
}
),
]
},
plugins: [
//定义打包后的路径以及css文件的名称
new ExtractTextWebpackPlugin('./css/main.css')
]
};
- 配置package.json
{
"scripts":{
"dev":"webpack-dev-server --mode development"
}
}
- 运行webpack进行打包
npm run build
6.2 Less文件的加载与提取分离
6.2.1 Less文件加载到JS文件中
- 安装less与less-loader依赖包
npm i less less-loader -D
- 添加style.less文件并设置样式
@a: pink;
#div-less{
color: @a;
ul{
li{
list-style: none;
height: 60px;
line-height: 30px;
}
}
}
- 将路径导入index.js文件内
import '../less/style.less';
- 配置webpack.config.js
module: {
rules: [
{
test: /\.less$/, //正则判断寻找.less文件
loader: ['style-loader','css-loader','less-loader']
}
],
}
- 运行webpack进行打包
npm run build
6.2.2 Less文件的提取分离
- 安装extract-text-webpack-plugin依赖包
npm i extract-text-webpack-plugin -D
- webpack.config.js配置
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules:[
{
test:/\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:'style-loader', // 回滚函数
use:['css-loader','less-loader']
}
}
),
]
},
plugins: [
//定义打包后的路径以及css文件的名称
new ExtractTextWebpackPlugin('./css/main.css')
]
};
- 配置package.json
{
"scripts":{
"dev":"webpack-dev-server --mode development"
}
}
- 运行webpack进行打包
npm run build
6.3 Sass文件的加载与分离
6.3.1 Sass文件加载到JS文件中
- 安装less与less-loader依赖包
npm i node-sass sass-loader -D
- 添加style.less文件并设置样式
$color: blue;
#div-sass{
color: $color;
ul{
li{
list-style: none;
height: 60px;
line-height: 30px;
}
}
}
- 将路径导入index.js文件内
import '../sass/style.scss';
- 配置webpack.config.js
module: {
rules: [
{
test: /\.(sass|scss)$/, //正则判断寻找.less文件
loader: ['style-loader','css-loader','sass-loader']
}
],
}
- 运行webpack进行打包
npm run build
6.3.2 Sass文件的提取分离
- 安装extract-text-webpack-plugin依赖包
npm i extract-text-webpack-plugin -D
- webpack.config.js配置
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules:[
{
test:/\.(sass|scss)$/,
use:ExtractTextWebpackPlugin.extract({
fallback:'style-loader', // 回滚函数
use:['css-loader','sass-loader']
}
}
),
]
},
plugins: [
//定义打包后的路径以及css文件的名称
new ExtractTextWebpackPlugin('./css/main.css')
]
};
- 配置package.json
{
"scripts":{
"dev":"webpack-dev-server --mode development"
}
}
- 运行webpack进行打包
npm run build
6.4 CSS冗余代码优化
- 安装purifycss-webpack与purify-css依赖包
npm i purifycss-webpack purify-css -D
- 安装glob依赖包
npm i glob -D # 用于扫描路径
- webpack.config.js配置
const purifyCssWebpack = require('purifycss-webpack');
const glob = require('glob');
module.exports = {
plugins: [
new purifyCssWebpack({
pahts:glob.sync(path.join(__dirname,'src/*.html'));
// glob 用于扫描项目的路径
});
]
};
6.5 图片文件的加载
- 安装url-loader与file-loader依赖包
cnpm i file-loader url-loader -D
- 在weboack.config.js文件配置module的rules规则
module: {
rules:[
{
test:/\.(png|jpg|gif)$/,
use:[{
loader:'url-loader',
options:{
limit:50, // 文件大小限制
outputPath:'images' //图片输出的目录路径
}
}
]
}
]
}
- style.css文件添加样式
body {
bsckground: url('./imgs/bz.jpg');
}
- 在index.js文件导入stylle.css文件
import './css/style.css';
- 开启开发服务器devServer查看
npm run dev
七、静态资源输出
开发项目中会有没有引用的图片资源或者其他静态资源这些静态资源有可能是文档,也有可能是一些额外的图片。打包时保留这些静态资源,直接打包到制定文件夹。
- 安装copy-webpack-plugin依赖包
npm i copy-webpack-plugin -D
- webapck.config.js的配置
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports{
plugins: [
new CopyWebapckPlugin([{
// 静态资源源文件路径
from:path.resolve(__dirname,'src/assets'),
to:'../public', // 打包的路径
}]
),
]
};
八、引入第三方库
8.1 使用npm下载引入
npm i jquery -S
8.2 使用ProvidePlugin
const webpack = require('webapck');
module.export = {
plugins: [
new webapck.ProvidePlugin({
$: 'jqury' // 引入Jquery库
});
]
};
九、提取第三方JS库
- 配置webpack.config.js
const webapck = require('webapck');
module.exports = {
entry: {
jquery: 'jquery'
}
optimization: {
splitchunks: {
cacheGroups:{
vendor: {
chunks: 'initial',
name:'jquery',
enforce:true
}
}
}
}
};
十、Vue.js的引入
- 安装vue依赖包
npm i vue -S
- 在Test.js文件中导入vue依赖包
import Vue from 'vue';
new Vue({
el:'#app',
data: {
message: 'Hello Webpack'
}
});
3.配置webpack.config.js
module.exports = {
resolve: {
// 取别名
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
};
webpack打包Vue后,会默认使用runtiom-only,此时代码Vue所指定的template不会被编译,浏览器不显示效果。故应该要对vue进行取别名的配置,将使用具有有runtiom-compiler模式的Vue版本。
- runtime-only : 代码中不包含有template
- runtime-compiler : 代码中包含有template,使用compiler对其进行编译
- 进行打包操作
npm run build
十一 、vue文件的封装处理
- 安装vue-loader与vue-template-compiler依赖包
npm vue-loader vue-template-compiler -D
- 创建Vue.vue文件
<template>
<h1 class="title">{{name}}</h1>
</template>
<script>
export default {
name: 'App',
data(){
return {
name: 'Vue文件的封装处理'
}
}
}
</script>
<style scoped>
.title {
color: blue;
}
</style>
- 配置webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
]
}
};
- 在main.js文件中导入Vue.vue
import App from './vue/App.vue'
new Vue({
el: '#app',
template: '<App/>',
components: {
App
}
})
- 在index.html文件中挂载对应ID
<!DOCTYPE>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
</head>
<body>
<div id = "app">
</div>
</body>
</html>