一、WebPack
1、资源:
官网:https://webpack.js.org/
github:https://github.com/webpack/webpack
中文网:https://www.webpackjs.com/
深入浅出webpack电子书:http://webpack.wuhaolin.cn/
2、搭建WebPack开发环境
(1)、安装NodeJS
在用 Webpack 执行构建任务时需要通过 webpack 可执行文件去启动构建任务,所以需要安装 webpack 可执行文件。 在安装 Webpack 前请确保你的系统安装了5.0.0及以上版本的 Node.js。
去https://nodejs.org/下载安装
(2)、安装webpack
安装方式如下:
npm i -g webpack
查看webpack版本,看看是否安装成功:
webpack -v
二、简单实例
2.1、创建一个项目
创建一个空项目,这里我使用WebStorm
项目结构:创建js、src目录
2.2、初始化项目
npm init -y
会生成package.json文件
2.3、安装webpack
webpack4需要安装webpack-cli:
npm i webpack webpack-cli --save-dev
2.4、创建目录与文件
src/bar.js
//定义模块 //部分依赖lodash中的join方法 import {join} from 'lodash' //导出一个默认模块 export default function bar() { function component() { //创建div元素 var element = document.createElement('div'); //使用join连接数组将结果写入元素的html中 element.innerHTML = join(['成功', 'webpack'], ' '); //返回 return element; } document.body.appendChild(component()); }
实现使用lodash的join 连接字符串,在网页中输出字符串
依赖lodash、npm安装lodash
npm i lodash --save
生成node-modules目录
src/index.js
//入口文件 //导入自定义好的模块 import bar from './bar'; //调用 bar();
创建配置文件webpack.config.js
//webpack配置文件 //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports={ //指定入口文件的位置 entry:"./src/index.js", //设置输出结果 output: { //路径,将相对路径转绝对路径 path:path.resolve(__dirname,'dist'), //文件 filename: "bundle.js" }
操作完成之后的目录结构:
2.5、使用webpack命令打包
可以指定配置文件
webpack --config webpack.config.js
也可以使用默认的配置文件
webpack
打包成功!结果
index.html
webpack创建dist文件在dist中生成打包文件,然后再index.html中引用index.js文件
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<script src="dist/bundle.js">script>
body>
html>
项目结构:
2.6、运行
三、深入了解webpack
3.1、入口(entry)、出口(output)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
可以通过在 webpack 配置中配置 entry 属性,来指定一个入口起点(或多个入口起点)。
多入口与多出口:
结合(二)中的实例:
创建src/app.js
//只是测试,弹出框 alert("App")
webpack.config.js
//webpack配置文件 //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{//多入口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //出口 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" } }
常用的占位:
- [hash]:模块标识符(module identifier)的 hash
- [chunkhash]:chunk 内容的 hash
- [name]:模块名称,key的名称,非文件名称
- [id]:模块标识符(module identifier)
- [query]:模块的 query,例如,文件名 ? 后面的字符串
打包
webpack
结果:
index.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<script src="dist/app.js">script>
<script src="dist/index.js">script>
body>
html>
四、模块转换器Loader
loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!
loader 是对应用程序中资源文件进行转换。它们是(运行在 Node.js 中的)函数,可以将资源文件作为参数的来源,然后返回新的资源文件。
资料:https://www.webpackjs.com/loaders/css-loader/
4.1、raw-loader(文件原始内容转换器)
安装
npm i --D raw-loader
创建.txt文件
src/text.txt
这是一个.txt文件
通过webpack.config.js配置、命令行或者内联使用 loader。
//webpack配置文件 //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{ //多人口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //设置输出结果 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' } ] } }
src/bar.js
//定义模块 //部分依赖lodash中的join方法 import {join} from 'lodash'; import txt from './text.txt' //导出一个默认模块 export default function bar() { function component() { //创建div元素 var element = document.createElement('div'); //使用join连接数组将结果写入元素的html中 element.innerHTML = join(['成功', 'webpack',txt], ' '); //返回 return element; } document.body.appendChild(component()) }
打包:
webpack
运行:
4.2、CSS Loader(样式处理)
安装
npm i style-loader css-loader -D
配置webpack.config.js
//webpack配置文件 //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{ //多人口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //设置输出结果 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' }, { test:/\.css/, use:['style-loader',{ loader: 'css-loader', options: { sourceMap:true } } } ] } }
src/css.css
div{ background-color: aqua; line-height: 50px; font-size: 20px; border-radius: 20px; }
src/bar.js
//定义模块 //部分依赖lodash中的join方法 import {join} from 'lodash'; import message from './text.txt'; import './css.css'; //导出一个默认模块 export default function bar() { function component() { //创建div元素 var element = document.createElement('div'); //使用join连接数组将结果写入元素的html中 element.innerHTML = join(['成功', 'webpack',message], ' '); console.log(message) //返回 return element; } document.body.appendChild(component()) }
打包
webpack
运行
注意事项
-
- rules里的数据类型为对象,每一个loader都是一个对象
- test表示loader要处理什么类型的文件,这里用了一个正则去匹配文件类型
- use表示要使用哪个loader,它的值是个数组,loader的使用顺序是从后往前
- 这个loader的意思为,在入口文件里找到.css类型的文件,先拿css-loader去处理成浏览器认识的css,再拿style-loader把处理后的css放在页面的style标签里
4.3、sass-loader(加载和转译 SASS/SCSS 文件)
安装
npm i sass-loader node-sass --D
src/Scss.scss
$height:50px; $color:#3366ff; div{ background: $color; height: $height; line-height: $height; color: rebeccapurple; padding-left: $height/5; }
配置webpack.config.json
//webpack配置文件 //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{ //多人口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //设置输出结果 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' }, { test:/\.css/, use:['style-loader',{ loader: 'css-loader', options: { sourceMap:true } }] },{ test: /\.scss$/, use: [{ loader: "style-loader" // 将 JS 字符串生成为 style 节点 }, { loader: "css-loader" // 将 CSS 转化成 CommonJS 模块 }, { loader: "sass-loader" // 将 Scss 编译成 CSS }] } ] } }
src/bar.js
//定义模块 //部分依赖lodash中的join方法 import {join} from 'lodash'; import message from './text.txt'; // import './css.css'; import './Scss.scss'; //导出一个默认模块 export default function bar() { function component() { //创建div元素 var element = document.createElement('div'); //使用join连接数组将结果写入元素的html中 element.innerHTML = join(['成功', 'webpack',message], ' '); console.log(message) //返回 return element; } document.body.appendChild(component()) }
打包:
webpack
运行:
4.4、url-loader(路径处理器)
Webpack 允许你在js文件中require图片 , 通过 url-loader和file-loader来预处理图片文件,将图片转换成base64编码。
安装
npm install --save-dev url-loader file-loader
配置webpack.config.json
//webpack配置文件 //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{ //多人口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //设置输出结果 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' }, { test:/\.css/, use:['style-loader',{ loader: 'css-loader', options: { sourceMap:true } }] },{ test: /\.scss$/, use: [{ loader: "style-loader" // 将 JS 字符串生成为 style 节点 }, { loader: "css-loader" // 将 CSS 转化成 CommonJS 模块 }, { loader: "sass-loader" // 将 Scss 编译成 CSS }] }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader' } ] } ] } }
src/bar.js
//定义模块 //部分依赖lodash中的join方法 import {join} from 'lodash'; import message from './text.txt'; // import './css.css'; import './Scss.scss'; import img from './img/1.png'; //导出一个默认模块 export default function bar() { function component() { //创建div元素 var element = document.createElement('div'); //使用join连接数组将结果写入元素的html中 element.innerHTML = join(['成功', 'webpack',message], ' '); console.log(message) //返回 return element; } function imgs(){ var img1=document.createElement("img"); img1.src=img; return img1; } document.body.appendChild(component());; document.body.appendChild(imgs()); }
报错:
安装
报错:
安装:
打包:
运行:
五、插件plugins
5.1、HTML Webpack Plugin(创建HTML插件)
该个插件的作用是用来自动生成html页面,既可以生成单个页面又可以生成多个页面,并且在生成前可以给它一些的配置参数,它会按照你想要的生成方式去生成页面。
安装
npm i html-webpack-plugin -D
配置webpack.config.js
//webpack配置文件 //导入用于生成html的插件 const HtmlWebpackPlugin=require("html-webpack-plugin"); //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{ //多人口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //设置输出结果 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' }, { test:/\.css/, use:['style-loader',{ loader: 'css-loader', options: { sourceMap:true } }] },{ test: /\.scss$/, use: [{ loader: "style-loader" // 将 JS 字符串生成为 style 节点 }, { loader: "css-loader" // 将 CSS 转化成 CommonJS 模块 }, { loader: "sass-loader" // 将 Scss 编译成 CSS }] }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader' } ] } ] }, plugins: [ //创建一个插件对象,并指定参数 new HtmlWebpackPlugin({ //指定生成的文件路径与名称 filename:"../Holle.html", //标题 title:"Hello!" }) ] }
打包
webpack
运行:
压缩:
//webpack配置文件 //导入用于生成html的插件 const HtmlWebpackPlugin=require("html-webpack-plugin"); // const MiniCssExtractPlugin=require("mini-css-extract-plugin"); //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{ //多人口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //设置输出结果 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' }, { test:/\.css/, use:['style-loader',{ loader: 'css-loader', options: { sourceMap:true } }] },{ test: /\.scss$/, use: [{ loader: "style-loader" // 将 JS 字符串生成为 style 节点 }, { loader: "css-loader" // 将 CSS 转化成 CommonJS 模块 }, { loader: "sass-loader" // 将 Scss 编译成 CSS }] }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader' } ] } ] }, plugins: [ //创建一个插件对象,并指定参数 new HtmlWebpackPlugin({ //指定生成的文件路径与名称 filename:"../Holle.html", //标题 title:"Hello!", minify:{ removeComments:true, //移除注释 collapseWhitespace:true, //折叠空格 //更新请参数https://github.com/kangax/html-minifier#options-quick-reference } }) ] }
结果:
DOCTYPE html><html><head><meta charset="UTF-8"><title>Hello!title>head><body><script type="text/javascript" src="dist/index.js">script><script type="text/javascript" src="dist/app.js">script>body>html>
5.2、Mini-css-extract-plugin(单独提取CSS插件)
安装
npm install --save-dev mini-css-extract-plugin
配置webpack.config.js
//webpack配置文件 //导入用于生成html的插件 const HtmlWebpackPlugin=require("html-webpack-plugin"); //导入用于提取css的插件 const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{ //多人口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //设置输出结果 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' }, { test:/\.css/, use:['style-loader',{ loader: 'css-loader', options: { sourceMap:true } }] },{ test: /\.scss$/, use: [{ loader:MiniCssExtractPlugin.loader //提取css并link }, { loader: "css-loader" // 将 CSS 转化成 CommonJS 模块 }, { loader: "sass-loader" // 将 Scss 编译成 CSS }] }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader' } ] } ] }, plugins: [ //创建一个插件对象,并指定参数 new HtmlWebpackPlugin({ //指定生成的文件路径与名称 filename:"../Holle.html", //标题 title:"Hello!", minify:{ removeComments:true, //移除注释 collapseWhitespace:true, //折叠空格 //更新请参数https://github.com/kangax/html-minifier#options-quick-reference } }), //创建一个用于提取css的插件对象 new MiniCssExtractPlugin({ filename:"[name]_[hash:10].css", chunkFilename:"[id]" }) ] }
生成的Hello.html
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello!title>
<link href="dist/index_67217d7d54.css" rel="stylesheet">head>
<body>
<script type="text/javascript" src="dist/index.js">script><script type="text/javascript" src="dist/app.js">script>body>
html>
运行
5.3、clean-webpack-plugin(删除或清理构建目录)
安装
npm i clean-webpack-plugin --save-dev
配置webpack.config.js里引入模块
//webpack配置文件 //导入用于删除或清理构建目录的插件 const CleanWebpackPlugin=require('clean-webpack-plugin'); //导入用于生成html的插件 const HtmlWebpackPlugin=require("html-webpack-plugin"); //导入用于提取css的插件 const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //依赖node中的path模块 const path=require('path'); //定义一个默认模块对象 module.exports= { //指定入口文件的位置 entry:{ //多人口 index:"./src/index.js", //入口 app:"./src/app.js" //入口 }, //设置输出结果 output: { //路径,将相对路径转绝对路径 path: path.resolve(__dirname, 'dist'), //多出口[name]为占位符,取entry中的key filename: "[name].js" }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' }, { test:/\.css/, use:['style-loader',{ loader: 'css-loader', options: { sourceMap:true } }] },{ test: /\.scss$/, use: [{ loader:MiniCssExtractPlugin.loader //提取css并link }, { loader: "css-loader" // 将 CSS 转化成 CommonJS 模块 }, { loader: "sass-loader" // 将 Scss 编译成 CSS }] }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader' } ] } ] }, plugins: [ //一定要放在前面:参数一为地址 new CleanWebpackPlugin(['./dist'],{}), //创建一个插件对象,并指定参数 new HtmlWebpackPlugin({ //指定生成的文件路径与名称 filename:"../Holle.html", //标题 title:"Hello!", minify:{ removeComments:true, //移除注释 collapseWhitespace:true, //折叠空格 //更新请参数https://github.com/kangax/html-minifier#options-quick-reference } }), //创建一个用于提取css的插件对象 new MiniCssExtractPlugin({ filename:"[name]_[hash:10].css", chunkFilename:"[id]" }) ] }
测试:
在dist创建无用文件,如:
打包:
webpack
结果:
六、DevServer开发服务器
webpack-dev-server就是一个基于Node.js和webpack的一个简易服务器。它在服务器端使用webpack-dev-middleware进行webpack构建打包;并在客户端注入一份runtime,用于接受服务器端的构建打包后信息。
在实际开发中我们可能会需要完成如下功能:
-
提供 HTTP 服务而不是使用本地文件预览;
-
监听文件的变化并自动刷新网页,做到实时预览;
-
支持 Source Map,以方便调试。
Webpack 原生支持上述第2、3点内容,再结合官方提供的开发工具 DevServer 也可以很方便地做到第1点。 DevServer 会启动一个 HTTP 服务器用于服务网页请求,同时会帮助启动 Webpack ,并接收 Webpack 发出的文件更变信号,通过 WebSocket 协议自动刷新网页做到实时预览。
6.1、快速开启DevServer
安装 DevServer:
npm i -D webpack-dev-server
安装成功后在项目的根目录下执行webpack-dev-server 命令, DevServer 服务器就启动了
webpack-dev-server
如果提示webpack-dev-server不是内部命令
解决办法:
在package.json里的scripts里加上"dev": "webpack-dev-server",然后执行命令npm run dev
package.json
{ "name": "Webpack_01", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack-dev-server" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "lodash": "^4.17.11" }, "devDependencies": { "clean-webpack-plugin": "^1.0.0", "css-loader": "^2.0.0", "file-loader": "^2.0.0", "html-webpack-plugin": "^3.2.0", "jimp": "^0.6.0", "mini-css-extract-plugin": "^0.5.0", "node-sass": "^4.11.0", "raw-loader": "^1.0.0", "responsive-loader": "^1.1.0", "sass-loader": "^7.1.0", "style-loader": "^0.23.1", "url-loader": "^1.1.2", "webpack": "^4.27.1", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.10" } }
执行命令npm run dev
npm run dev
在浏览器里输入地址http://localhost:8081
结果: