一、初识webpack
javascript 应用程序的静态模块打包工具,其作用:分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),
并生成一个或多个 bundle,将其打包为合适的格式以供浏览器使用
概念图解: webpack官网
二、环境安装
如果具备该环境,此步骤可以跳过
Homebrew
打开终端,执行以下命令安装Homebrew:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Node
打开终端,执行以下命令安装node: brew install node
查看版本,检查是否安装成功: node -v npm -v
镜像切换 Cnpm
打开终端,执行以下命令安装cnpm:
npm install cnpm -g --registry=https://registry.npm.taobao.org
查看版本,检查是否安装成功: cnpm -v
webpack
在webpack4.x之后,其脚手架webpack-cli需要单独安装:
npm install webpack webpack-cli --global //这是安装全局webpack及webpack-cli模块
npm install webpack webpack-cli --save-dev //这是安装本地项目模块
三、小试牛刀
- 「新建文件目录 webpack-simple,并生成package.json」
1. mkdir webpack-simple
2. npm init 或 npm init -y (指定模版生成package.json)
3. npm install webpack webpack-cli --save-dev
- 「项目结构并生成」
根目录下新建 src 文件夹 和 dist 文件夹,创建对应的脚本文件:
1. dist文件夹下 新建 index.html
2. src文件夹下 新建 index.js
3. src文件夹下 新建 hello.js
index.html: 引入打包后的js文件
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Webpack Project</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
<!--这是打包之后的js文件,我们暂时命名为bundle.js-->
</body>
</html>
hello.js
module.exports = function() {
let hello = document.createElement('div')
hello.innerHTML = 'welcome to webpack knowledge world!'
return hello
}
在index.js中引入 hello.js:
const hello = require('./hello')
document.querySelector('#root').appendChild(hello());
在以上操作过程中,已经完成了基本的文件组成,同时也把hello.js 合并到 index.js中,打包时,只需要输出index.js文件即可
// 在终端中根路径下使用如下命令进行打包:
webpack src/index.js output dist/bundle.js
执行结果可以看到 把 src 文件夹下的 index.js 文件打包到 dist 文件下的 bundle.js,这时就生成了 bundle.js 供 index.html 文件引用。那么打开index.html就可以看到完整的页面效果了
- 「webpack.config.js」
根目录下新建配置文件 webpack.config.js 用来配置打包方式:
const path = require('path') // 处理绝对路径
module.exports = {
entry: path.join(__dirname, '/src/index.js'), // 入口文件
output: {
path: path.join(__dirname, '/dist'), //打包后的文件存放的地方
filename: 'bundle.js' //打包后输出文件的文件名
}
}
在终端根路径下执行命令 webpack
就可进行打包,该命令会自动引用 webpack.config.js 文件中的配置选项
- 「构建本地服务器并优化执行方式」
//安装 webpack-dev-server
npm i webpack-dev-server -D
// webpack.config.js
const path = require('path')
module.exports = {
entry: path.join(__dirname, '/src/index.js'), // 入口文件
output: {
path: path.join(__dirname, '/dist'), //打包后的文件存放的地方
filename: 'bundle.js' //打包后输出文件的文件名
},
devServer: {
hot:true, //开启热更新
contentBase: './dist', // 本地服务器所加载文件的目录
port: '8088', // 设置端口号为8088
inline: true, // 文件修改后实时刷新
historyApiFallback: true //不跳转
}
}
// package.json文件更新scripts命令
{
"name": "webpack-simple",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack", //项目打包
"watch": "webpack --watch",// 加--watch自动监听代码的变化
"dev": "webpack-dev-server --open" //配置热更新
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.42.0",
"webpack-cli": "^3.3.11"
},
"dependencies": {
"webpack-dev-server": "^3.10.3"
}
}
采用命令进行本地运行或项目打包
//终端下执行命令
1. npm run dev (webpack-dev-server 就是启动服务器的命令,--open 是用于启动完服务器后自动打开浏览器) //启动服务器
2. npm run build //执行打包命令
此时,基本的项目配置已经准备完成,只需要输入 npm run dev 就可以在http://localhost:8088/
中查看页面 效果了。
Loader
webpack可以使用loader 来预处理那些非 JavaScript 文件,就是通过使用不同的Loader,webpack可以把不同的静态文件都编译成js文件,比如css,sass,less,ES6/7,vue,JSX等
概念图解: 官网
处理JS文件
- 「babel-loader」
作用: 实现对使用了ES2015+语法的.js文件进行处理.
命令:
npm/cnpm install babel-loader --save-dev
- 「babel-core」
作用 : 在于提供一系列api。这便是说,当webpack使用babel-loader处理文件时,babel-loader实际上调用了babel-core的api
命令:
npm/cnpm install babel-core --save-dev
- 「babel-preset-env」
作用: 在于告诉babel使用哪种转码规则进行文件处理
命令:
npm/cnpm install babel-preset-env --save-dev
- 「webpack.config.js的配置」
const path = require('path');//物理路径
//__dirname,当前运行环境下的变量,也就是当前环境下的绝对路径,后面会跟着一个相对路径
{
...
module:{
rules:[
{
test:/\.js$/,
include:path.resolve(__dirname, 'src'),
exclude: path.resolve(__dirname,"node_modules"), // /node_modules/, //指定排除处理的范围文件,提高打包的速度,可以是正则表达式,还有绝对路径
loader: "babel-loader"
}
]
}
...
}
- 「项目构建」
在基础的项目结构下,src目录下新建 babel-test.js文件,并引入到index.js中
//babel-test.js代码
module.exports = {
showToast:function () {
alert('用来测试babel-loader引入的弹窗')
}
}
//index.js代码
const hello = require('./hello')
const babelTest = require('./babel-test')
document.querySelector('#root').appendChild(hello());
babelTest.showToast()
执行命令
npm run dev
如出现错误:
Error: Cannot find module '@babel/core'
那是因为babel-loader的版本过高, 找不到babel-core. 两者之间不匹配, 这个时候的办法, 是先重新安装babel-loader,回退版本到7.0多
“cnpm install babel-loader@7.1.5 --save-dev”
或者 “npm install @babel/core --save-dev”
命令成功执行后,可以在浏览器 8080页面,查看到babel-test中 引入的弹窗效果。这样对于babel-loader的配置,也基本成功完成了.
处理CSS文件
- 「style-loader」
作用: 能够在需要载入的html中创建一个<style></style>标签,style-loader加载到的css样式动态的添加该标签中.
命令:
npm/cnpm install style-loader --save-dev
- 「css-loader」
作用: 允许在js中import一个css文件,会将css文件当成一个模块引入到js文件中. 只会加载引入到js文件中的css文件.
命令:
npm/cnpm install css-loader --save-dev
- 「简单配置css样式支持」
在基础的项目结构下,src目录下新建 style/style.css文件,并引入到index.js中
<!--style/style.css代码-->
.container{
width:200px;
height:200px;
background-color:red
}
//index.js代码
import './style/style.css' ; //对css文件进行引入
const hello = require('./hello')
const babelTest = require('./babel-test')
document.querySelector('#root').appendChild(hello());
babelTest.showToast()
<!--dist/index.html代码-->
<body>
<div id="root"></div>
<div class="container"></div>
<script src="dist/bundle.js"></script>
<!--这是打包之后的js文件,我们暂时命名为bundle.js-->
</body>
<!--webpack.config.js配置-->
module.exports = {
module: {
rules: [
{
test: /\.css$/, //匹配以css为后缀的文件
use: ['style-loader', 'css-loader'],//loader的执行顺序是从右向左,从下到上。css-loader:分析几个css文件之间的关系,最终合并为一个css。style-loader:在得到css生成的内容时,把其挂载到html的head里,成为内联样式。
},
],
},
};
执行命令 npm run dev
可以查看到css样式已经成功的加载到页面中
处理静态SASS、LESS文件
- 「sass-loader」
作用: 对项目中scss文件进行处理
命令:
npm/cnpm install sass-loader --save-dev
npm/cnpm install node-sass --save-dev
- 「less-loader」
作用: 对项目中的less文件进行处理
命令:
cnpm install less --save-dev
npm/cnpm install less-loader --save-dev
- 「postcss-loader」
作用: 其主要是对css文件的预处理,autoprefixer是它的一个插件,主要是对css文件添加兼容性前缀
常见浏览器前缀:
1. Trident内核:主要代表为IE浏览器, 前缀为-ms
2. Gecko内核:主要代表为Firefox, 前缀为-moz
3. Presto内核:主要代表为Opera, 前缀为-o
4. Webkit内核:产要代表为Chrome和Safari, 前缀为-webkit
命令:
npm/cnpm install postcss-loader --save-dev
cnpm install autoprefixer --save-dev. //属于postcss的插件
在项目中,提供两种方式分别对 autoprefixer
的配置支持
//1.在项目根目录下创建 postcss.config.js文件
module.exports = {
plugins: [
require('autoprefixer')
]
}
//2. 直接在webpack.config.js文件配置对loader的特别支持 如下(webpack.config.js的配置)
- 「webpack.config.js的配置」
module.exports = {
...
module: {
test:/\.(sc|le|c)ss$/, // 项目中如果有多个ss文件结尾时,正则表达式可以这么使用,最新执行的再前面
use:[{
loader:'style-loader'
},{
loader:'css-loader',
options:{
importLoaders:1, ////如果sass文件里还引入了另外一个sass文件,另一个文件还会从postcss-loader向上解析。如果不加,就直接从css-loader开始解析。
modules: true //开启css的模块打包。css样式不会和其他模块发生耦合和冲突
}
},{
loader:"less-loader"
},{
loader:"sass-loader"
},{
loader:'postcss-loader', //autoprefixer使用该插件为各浏览器支持的属性加上前缀
options:{
plugins:[require("autoprefixer")("last 5 versions")]
}
},
],
include:path.resolve(__dirname, 'src'),
},
};
处理资源文件
- 「file-loader的使用」
作用: 对项目中引入的资源文件(图片)进行处理,解决CSS等文件中的引入图片路径问题
命令:
npm/cnpm install file-loader --save-dev
//webpack.config.js配置
module.exports = {
//配置模块,主要用来配置不同文件的加载器
module: {
//配置模块规则
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/, //正则匹配要使用相应loader的文件
use: [
{
loader: 'file-loader', //要用到的loader
options: {
//palceholder占位符
name:'[name].[ext]', //打包后的图片名字,后缀和打包的之前的图片一样
outputPath: 'images/' //图片打包后的地址
},
},
],
},
],
},
};
- 「url-loader的使用」
作用:将小图片转换成base64格式,其已经具备了file-loader的功能,使用时,可以不引用file-loader.
url-loader可以将图片转成base64字符,能更快的加载图片,一旦图片过大,就会使用file-loader的加载本地图片
命令:
npm/cnpm install url-loader --save-dev
<!--webpack.config.js配置-->
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif|bmp/)$/i,
use: [
{
loader: 'url-loader',
options: {
name:'[name].[ext]',
outputPath: 'images/',
limit: 8192 //小于8192b,就可以转化成base64格式。大于就会打包成文件格式
}
}
]
}
]
}
}
- 「file-loader和url-loader使用注意:」
1. 在css文件中对图片资源文件的引入可以使用相对路径:
app.css文件中:
.imgClass{
width:400px;
height: 400px;
background: url('../assets/test.jpg');
}
.imgSize{
width:400px;
height: 400px;
}
2. 在html中如果使用img标签的src 对图片进行使用,需要“使用绝对路径”. 如果要使用相对路径,则需要如下:
<div class="imgClass"></div>
<img class="imgSize" src="${require('./src/assets/bg.jpg')}"/>
- 「image-webpack-loader」
作用:对引入项目中的图片文件进行压缩处理
命令:
npm/cnpm install image-webpack-loader --save-dev
<!--webpack.config.js配置 -->
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif|bmp/)$/i,
use: [
{
loader: 'url-loader',
options: {
name:'[name].[ext]',
outputPath: 'images/',
limit: 8192 //小于8192b,就可以转化成base64格式。大于就会打包成文件格式
}
},
{
loader:'image-webpack-loader', //对图片资源进行压缩处理
}
]
}
]
}
}
处理HTML文件
- 「html-loader」
作用: 对项目中引入的模版html文件进行处理(必须在js文件中引入)
命令:
npm/cnpm install html-loader --save-dev
完整的Loader支持配置
- 「项目结构」
在webpack-simple
项目中,我们的文件结构树如下:
在src目录下,存在components文件夹 和 index.js
文件, 代码引入如下:
//components/layer.js代码
import template from './layer.html'
import "./layer.css";
// import "./layer.less";
function layer (){
return{
name:"layer",
tpl:template
}
}
//导出
export default layer;
//components/layer.html代码
<div class="layer">
<div>this is a layer</div>
</div>
//index.js对layer模版的引入
import './style/style.css' ; //对css文件进行引入
//模版引入
import Layer from './components/layer/layer.js'
const hello = require('./hello')
const babelTest = require('./babel-test')
document.querySelector('#root').appendChild(hello());
babelTest.showToast()
const App = function (){
var dom = document.getElementById('layer');
dom.innerHTML = new Layer().tpl;
console.log(dom);
console.log(Layer);
}
new App();
<!--index.html中使用layer模版-->
<body>
<div id="root"></div>
<div class="container"></div>
<div id="layer"></div>
<script src="dist/bundle.js"></script>
<!--这是打包之后的js文件,我们暂时命名为bundle.js-->
</body>
- 「webpack.config.js的配置」
//处理绝对路径
const path = require('path');
const webpack = require('webpack');
module.exports = {
//默认是production,打包的文件默认被压缩。开发时可以设置为development,不被压缩
mode: 'production',
entry: path.join(__dirname, 'src/index.js'), //入口文件
output: {
path: path.resolve(__dirname, 'dist'), //定位,输出文件的目标路径
filename: 'bundle.js', //可自定命名js/[name].js,打包后输出文件的文件名称, 文件名默认[name].js, 可以在前面加上相对路径,生成包裹js文件的文件夹
},
devServer: {
hot: true,
contentBase: './dist', //本地服务器所加载文件的目录
port: '8088', //设置端口号8088
inline: true, //文件修改后热更新
historyApiFallback: true // 不跳转
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
include: path.resolve(__dirname, 'src'),
exclude: path.resolve(__dirname, "node_modules"), // /node_modules/, //指定排除处理的范围文件,提高打包的速度,可以是正则表达式,还有绝对路径
}, {
test: /\.(sc|le|c)ss$/, // 项目中如果有多个ss文件结尾时,正则表达式可以这么使用,最新执行的再前面
// loader:'style-loader!css-loader!less-loader' 没有postcss-loader可以直接这样使用
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader',
options: {
importLoaders: 1
}
}, {
loader: "less-loader"
}, {
loader: "sass-loader"
}, {
loader: 'postcss-loader', //autoprefixer使用该插件为各浏览器支持的属性加上前缀
options: {plugins: [require("autoprefixer")("last 5 versions")]}
},
],
include: path.resolve(__dirname, 'src'),
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i, //使用file-loader对资源文件的引入,i不区分大小写
include: path.resolve(__dirname, 'src'),
use: [
// {
// loader:'file-loader',
// options:{
// name:'assets/[name]-[hash:5].[ext]', //设置资源图片打包后的地址
// }
// },
{
loader: 'url-loader',
options: {
limit: 20000, //限制图片的最大字节
name: 'assets/[name]-[hash:5].[ext]', //设置资源图片打包后的地址
}
},
{
loader: 'image-webpack-loader', //对图片资源进行压缩处理
}
]
},
{
test: /\.html$/, //使用html-loader对html模版内容进行引入.
// include:path.resolve(__dirname, 'src'),
loader: "html-loader"
}]
}
}
Plugin
plugin是webpack的支柱, 主要是为了解决loader无法实现的其他事情.想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。
多数插件可以通过选项(option)自定义,你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例
概念图解:官网
- 「webpack-dev-server」
作用: 搭建本地服务器,实现热更新,可解决每次在src里编写完代码都需要手动重新运行 npm run dev
命令:
npm install webpack-dev-server --save-dev
属性:
1. contentBase :配置开发服务运行时的文件根目录
2. open :自动打开浏览器
3. host:开发服务器监听的主机地址
4. compress :开发服务器是否启动gzip等压缩
5. port:开发服务器监听的端口
//处理绝对路径
const path = require('path');
const webpack = require('webpack');
module.exports = {
//默认是production,打包的文件默认被压缩。开发时可以设置为development,不被压缩
mode: 'production',
entry: path.join(__dirname, 'src/index.js'), //入口文件
output: {
path: path.resolve(__dirname, 'dist'), //定位,输出文件的目标路径
filename: 'js/[name].js', //打包后输出文件的文件名称, 文件名默认[name].js, 可以在前面加上相对路径,生成包裹js文件的文件夹
},
//本地服务
devServer: {
hot: true,开启热更新
contentBase: './dist', //本地服务器所加载文件的目录
port: '8088', //设置端口号8088
inline: true, //文件修改后热更新
historyApiFallback: true // 不跳转
}
}
//package.json配置
{
...
"name": "webpack-simple",
"version": "1.0.0",
"description": "webpack knowledge",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev": "webpack-dev-server --open"
"watch": "webpack --watch",// 加--watch自动监听代码的变化
},
"keywords": [],
"author": "chonglou",
"license": "ISC",
...
}
- 「html-webpack-plugin」
作用: 打包项目中的html文件, 并生成对应打包的html文件.
命令:
npm/cnpm install html-webpack-plugin --save-dev
属性:
1.file: 指定生成的文件
2.filename: 指定生成的文件名称, 优先级比file高, 两者取一即可
3.template: 需要被打包的html文件路径
4.inject: 主要是指定引入的js文件写入到html文件的位置.
主要有true(默认值,body底部)、body(body底部)、head(html标签的head)、false(不写入生成的js文件,基本不会用)
5.minify对象:主要是对html文件进行压缩,可去npm官网(https://www.npmjs.com/package/html-webpack-plugin)查看对应的属性配置
6.chunks:指定哪些需要被引入打包的模块
7.excludeChunks:指定哪些不需要被引入打包的模块,而其他的chunks将会被引入. 且与优先级高于chunks,
也就是说当两者同时存在时,excludeChunks如果包含chunks中的chunk,则该chunk也不会被引入
//webpack.config.js配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //打包html文件
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'), //定位,输出文件的目标路径
filename: 'js/[name].js',//文件名默认[name].js,
},
// webpack 中对于plugin的学习
plugins: [ //数组, 支持生成多页面的html文件
new HtmlWebpackPlugin({ //将模板的头部和尾部添加css和js模板,dist 目录发布到服务器上,项目包。可以直接上线
file: 'app.html', //指定要生成的文件
filename: 'app.html', //指定要生成的文件名称,优先级比file高, 两者指定一个就可以,加上hash会每次生成不同的html文件
template: 'index.html', //需要被打包的模版html
inject: 'body', //指定脚本插入的标签位置, 可以是head,body等标签
title: 'webpack is good',
minify: { //对html文件进行压缩
removeComments: true, //删除打包的文件内部代码注释
collapseWhitespace: true, //删除空格
},
}),
],
...
}
- 「clean-webpack-plugin」
作用: 自动清除上一次打包的dist文件
命令:
npm/cnpm install clean-webpack-plugin --save-dev
//webpack.config.js配置
const path = require('path');
//const CleanWebpackPlugin = require('clean-webpack-plugin'); //旧语法
const {CleanWebpackPlugin} = require("clean-webpack-plugin"); //clean-webpack-plugin3.x版本之后,更新了引入方式
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].js',//文件名默认[name].js,
},
plugins: [
new HtmlWebpackPlugin({
template: 'index.html' //在打包之后,以.html为模板,把打包生成的js自动引入到这个html文件中
}),
// new CleanWebpackPlugin(['dist']), // 在打包之前,可以删除dist文件夹下的所有内容
new CleanWebpackPlugin() //clean-webpack-plugin3.x版本之后,不需要指定目录删除
]
};
- 「extract-text-webpack-plugin」
作用: 抽离 css 样式,防止将样式打包在 js 中引起页面样式加载错乱的现象
命令:
npm/cnpm install extract-text-webpack-plugin@next --save-dev
//webpack.config.js的配置
const ExtractTextPlugin = require('extract-text-webpack-plugin') //引入分离插件
module.exports = {
module: {
rules: [
{
test: /\.css$/, // 正则匹配以.css结尾的文件
use: ExtractTextPlugin.extract({
// 相当于回滚,经postcss-loader和css-loader处理过的css最终再经过style-loader处理
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader']
})
}
]
},
plugins: [
new ExtractTextPlugin('css/index.css') // 将css分离到/dist文件夹下的css文件夹中的index.css
]
}
在其执行npm run build
之后,在dist目录下会自动生成 css目录及其下index.css文件
- 「purifycss-webpack、 purify-css、 glob」
purifycss-webpack的作用: 消除冗余的css,避免重复代码样式;结合clean-webpack-plugin使用
命令:
npm/cnpm install purifycss-webpack purify-css glob --save-dev
//webpack.config.js配置
const PurifyCssWebpack = require('purifycss-webpack') // 引入PurifyCssWebpack插件
const glob = require('glob') // 引入glob模块,用于扫描全部html文件中所引用的css
plugins: [
new PurifyCssWebpack({
paths: glob.sync(path.join(__dirname, 'src/*.html')) // 同步扫描所有html文件中所引用的css
})
]
- 「plugin对多页面项目的配置支持」
//webpack.config.js多页面配置
const HtmlWebpackPlugin = require('html-webpack-plugin'); //打包html文件
module.exports = {
//context:'' //整个环境的上下文, 也就是项目根目录
entry: { //入口文件, 在vue-cli中是main.js
main: './src/index.js',
app: './src/app.js',
home: './src/home.js',
mine: './src/mine.js',
},
output: { //webpack如何向外输出
path: path.resolve(__dirname, 'dist'), //定位,输出文件的目标路径
filename: 'js/[name].js',//文件名默认[name].js, 可以在前面加上相对路径,生成包裹js文件的文件夹
//也可用hash chunkhash结合配置. [name]-[hash].js [name]-[chunkhash].js.
//使用chunkhash,在打包的时候,如果文件无修改,则不会在打包. 等同于版本号,使用用于多页面
publicPath: 'http://cdn.com/' //公共路径, 可以理解为绝对地址(域名), 设置publicpath,在打包输出的时候,
//在html中引入的路径会以publicPath+path+filename.js这两个路径拼接后的文件名称引入
},
// webpack 中对于plugin的学习
plugins: [ //数组, 支持生成多页面的html文件
new HtmlWebpackPlugin({ //将模板的头部和尾部添加css和js模板,dist 目录发布到服务器上,项目包。可以直接上线
file: 'app.html', //指定要生成的文件
filename: 'app.html', //指定要生成的文件名称,优先级比file高, 两者指定一个就可以,加上hash会每次生成不同的html文件
template: 'index.html', //需要被打包的模版html
inject: 'body', //指定脚本插入的标签位置, 可以是head,body等标签
title: 'webpack is good',
minify: { //对html文件进行压缩
removeComments: true, //删除打包的文件内部代码注释
collapseWhitespace: true, //删除空格
},
chunks: ['main', 'app']
}),
new HtmlWebpackPlugin({ //home页面
filename: 'home.html',
template: 'home.html',
inject: true,
chunks: ['main', 'home'] //chunks属性,指定每一个模版要引入的chunk(js文件),而且是作为数组存在,其内部对象为要引入的chunk名称.
}),
new HtmlWebpackPlugin({ //mine页面
filename: 'mine.html',
template: 'mine.html',
inject: true,
//chunks:['main','home'], excludeChunks和chunks最好两者取其一,互不包含
excludeChunks: ['home', 'app'], //指定哪些不被引入的chunk(js文件),而剩下的其他chunk,将在该模版进行引入, 它和chunks属性对立,
//且与优先级高于chunks,也就是说当两者同时存在时,excludeChunks如果包含chunks中的chunk,则该chunk也不会被引入
})
],
...
}
完整项目
基于以上学习过程中,我们已经了解到webpack各项配置的使用,在此我们结合各项功能完整输出一个webpack构建而成的项目结构:
基于原有的基础上,删除dist文件,保留src文件,并在根目录下创建index.html,其内容如下:
<!--index.html代码-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack 入门学习</title>
</head>
<body>
<div id="root"></div>
<div class="container"></div>
<div id="layer"></div>
</body>
</html>
完整的webpack.config.js配置结构
//处理绝对路径
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const ExtractTextPlugin = require('extract-text-webpack-plugin') //引入分离插件
const PurifyCssWebpack = require('purifycss-webpack') // 引入PurifyCssWebpack插件
const glob = require('glob') // 引入glob模块,用于扫描全部html文件中所引用的css
module.exports = {
//默认是production,打包的文件默认被压缩。开发时可以设置为development,不被压缩
mode: 'production',
entry: path.join(__dirname, 'src/index.js'), //入口文件
output: {
path: path.resolve(__dirname, 'dist'), //定位,输出文件的目标路径
filename: 'js/[name].js', //打包后输出文件的文件名称, 文件名默认[name].js, 可以在前面加上相对路径,生成包裹js文件的文件夹
},
devServer: {
hot: true,
contentBase: './dist', //本地服务器所加载文件的目录
port: '8088', //设置端口号8088
inline: true, //文件修改后热更新
historyApiFallback: true // 不跳转
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
include: path.resolve(__dirname, 'src'),
exclude: path.resolve(__dirname, "node_modules"), // /node_modules/, //指定排除处理的范围文件,提高打包的速度,可以是正则表达式,还有绝对路径
}, {
test: /\.css$/, // 正则匹配以.css结尾的文件
use: ExtractTextPlugin.extract({
// 相当于回滚,经postcss-loader和css-loader处理过的css最终再经过style-loader处理
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader']
})
}, {
test: /\.(sc|le)ss$/, // 项目中如果有多个ss文件结尾时,正则表达式可以这么使用,最新执行的再前面
// loader:'style-loader!css-loader!less-loader' 没有postcss-loader可以直接这样使用
use: [{
loader: "less-loader"
}, {
loader: "sass-loader"
}, {
loader: 'postcss-loader', //autoprefixer使用该插件为各浏览器支持的属性加上前缀
options: {plugins: [require("autoprefixer")("last 5 versions")]}
},
],
include: path.resolve(__dirname, 'src'),
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i, //使用file-loader对资源文件的引入,i不区分大小写
include: path.resolve(__dirname, 'src'),
use: [
// {
// loader:'file-loader',
// options:{
// name:'assets/[name]-[hash:5].[ext]', //设置资源图片打包后的地址
// }
// },
{
loader: 'url-loader',
options: {
limit: 20000, //限制图片的最大字节
name: 'assets/[name]-[hash:5].[ext]', //设置资源图片打包后的地址
}
},
{
loader: 'image-webpack-loader', //对图片资源进行压缩处理
}
]
},
{
test: /\.html$/, //使用html-loader对html模版内容进行引入.
// include:path.resolve(__dirname, 'src'),
loader: "html-loader"
}]
},
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
filename: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
}
}),
new CleanWebpackPlugin(), // 在打包之前,可以删除dist文件夹下的所有内容
// new webpack.HotModuleReplacementPlugin()
new ExtractTextPlugin('css/index.css'), // 将css分离到/dist文件夹下的css文件夹中的index.css
new PurifyCssWebpack({
paths: glob.sync(path.join(__dirname, 'src/*.html')) // 同步扫描所有html文件中所引用的css
})
]
}
执行命令npm run dev
和 npm run build
,可以看到在项目结构下,自动生成dist文件以及对应的资源文件,同时也可以在页面上看到对应的响应效果,至此webpack的项目就搭建完成了。
本文使用 mdnice 排版