1. clean-webpack-plugin 清除输出目录
const { CleanWebpackPlugin } = require('clean-webpack-plugin')module.exports = {mode: 'development',entry: './src/index.js',output: {filename: 'index.js',},plugins: [new CleanWebpackPlugin()]}
2. html-wepack-plugin 生成静态的html文件,文件自动引入生成的js,当js更新的时候,会自动更新引入链接
单个chunk
const { CleanWebpackPlugin } = require('clean-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin');;module.exports = {mode: 'development',entry: './src/index.js',output: {filename: 'index[chunkhash:2].js',},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin()]}
多个chunk,多个页面
const { CleanWebpackPlugin } = require("clean-webpack-plugin")const HtmlWebpackPlugin = require('html-webpack-plugin');;module.exports = {mode: 'development',entry: {home: './src/index.js',a: './src/a.js',},output: {filename: '[name][chunkhash:2].js',},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './public/index.html',//以哪个html模板作为生成html文件的模板chunks: ['home'], //使用那个chunk来作为打包后,index.html页面上引入的js,默认为全部filename: 'home.html',//生成html页面的文件名,默认的为index.html}),new HtmlWebpackPlugin({template: './public/index.html',//以哪个html模板作为生成html文件的模板chunks: ['a'], //使用那个chunk来作为打包后,index.html页面上引入的js,默认为全部filename: 'a.html',//生成html页面的文件名,默认的为index.html})]}
3. copy-webpack-plugin 复制某个文件夹的的静态资源内容到另一个文件夹里面去
例子:
- 在公共模板的文件夹public里面,index.html文件引入了当前文件下img下面的一张图片,
问题:
1. 由于图片和入口的js并没有依赖关系,导致图片不会被打包,
const { CleanWebpackPlugin } = require("clean-webpack-plugin")const HtmlWebpackPlugin = require('html-webpack-plugin');const CopyWebpack=require('copy-webpack-plugin');module.exports = {mode: 'development',entry: {home: './src/index.js',a: './src/a.js',},output: {filename: '[name][chunkhash:2].js',},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './public/index.html',//以哪个html模板作为生成html文件的模板chunks: ['home'], //使用那个chunk来作为打包后,index.html页面上引入的js,默认为全部filename: 'home.html',//生成html页面的文件名,默认的为index.html}),new HtmlWebpackPlugin({template: './public/index.html',//以哪个html模板作为生成html文件的模板chunks: ['a'], //使用那个chunk来作为打包后,index.html页面上引入的js,默认为全部filename: 'a.html',//生成html页面的文件名,默认的为index.html}),new CopyWebpack([ //每一个对象都是一个复制规则{from:'./public',to:'./' //to 的默认文件夹位置就是默认输出目录(dist),如果负值的文件和目标文件目录冲突的,就会放弃复制}])]}
4. 开发服务器
在开发阶段,目前遇到的问题是打包,运行,调试过程过于繁琐,回顾一下我们的操作流程:
- 编写代码
- 控制台运行命令打包
- 打开页面看效果
- 继续编写代码->回到步骤2
并且,我们往往希望把最终生成的代码和页面部署到服务器上,来模拟真是的环境
为了解决这些问题,webpack官方制作了一个单独的库Lwebpack-dev-server
它既不是plugin也不是loader
来看看怎么使用
- 安装 npm i webpack-dev-server
执行 webpack-dev-server 命令
webpack-dev-server 命令几乎支持所有的webpack命令参数,如—config,-env等等,你可以把它当做webpack命令来使用
这个命令是专门为开发阶段做准备的,真正的服务器部署的时候还是使用webpack命令
当我们执行webpack-dev-server命令后,它做了如下操作
- 执行内部webpack命令,传递命令参数
- 开启watch
注册hooks: 类似于plugin,webpack-dev-server 会向webpack中注册一些钩子函数,主要功能如下
- 将资源列表(assets)保存起来
2. 禁止webpack输出文件
- 将资源列表(assets)保存起来
用express开启一个服务器,监听某个端口,当请到达以后,根据请求的路径,给予相应的资源内容
配置
针对webpack-dev-server的配置,参考
https://www.webpackjs.com/configuration/dev-server/
常见配置
const { CleanWebpackPlugin } = require("clean-webpack-plugin")const HtmlWebpackPlugin = require('html-webpack-plugin');const CopyWebpack=require('copy-webpack-plugin');module.exports = {mode: 'development',plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './public/index.html',//以哪个html模板作为生成html文件的模板}),new CopyWebpack([ //每一个对象都是一个复制规则{from:'./public',to:'./' //to 的默认文件夹位置就是默认输出目录(dist)}])],devServer:{port:8001,//端口号open:true,//自动打开浏览器窗口index:'index.html', //默认请求的文件名openPage:'index.html',// 默认打开文件proxy:{'/api':{target:'http://open.duyiedu.com', //前面是一个正则,表示只要是包含api的请求路径,前面的主机地址都匹配为http://open.duyiedu.com,例如你访问的是http://localhost:8080/api/student/findAll会被替换成http://open.duyiedu.com/api/student/findAllchangeOrigin:true, //更改请求头中的host,和origin}},stats:{modules:false,//打包的时候,不输出打包modules的日志信息colors:true,//打包输出的日志,颜色区分}}}
5. 普通文件处理 file-loader5.0.2,生成依赖文件到输出目录,然后将模块文件设置为:导出一个路径
//file-loaderfunction loader(source){// source:文件内容(图片内容 buffer)// 1. 生成一个具有相同文件内容的文件到输出目录// 2. 返回一段代码 export default "文件名"}
测试代码
//希望导入的模块是一个可用的资源路径const png = require('./assets/bird.jpeg').default;if (Math.random() < 0.5) {var img = document.createElement('img');img.src = png;document.body.append(img);}
配置代码
const { CleanWebpackPlugin } = require("clean-webpack-plugin")const HtmlWebpackPlugin = require('html-webpack-plugin');const CopyWebpack = require('copy-webpack-plugin');module.exports = {mode: 'development',plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin()],module: {rules: [{test: /\.(png)|(gif)|(jpeg)$/,use: [{loader: 'file-loader',options: {name: '[path][name][hash:].[ext]' //这里面的hash是文件内容的hash跟contenthash是一样的}}]}]},devServer: {port: 8001,//端口号open: true,//自动打开浏览器窗口index: 'index.html', //默认请求的文件名proxy: {'/api': {target: 'http://open.duyiedu.com', //前面是一个正则,表示只要是包含api的请求路径,前面的主机地址都匹配为http://open.duyiedu.com,例如你访问的是http://localhost:8080/api/student/findAll会被替换成http://open.duyiedu.com/api/student/findAllchangeOrigin: true, //更改请求头中的host,和origin}},stats: {modules: false,//打包的时候,不输出打包modules的日志信息colors: true,//打包输出的日志,颜色区分}}}
6. url-loader 3.0.0将依赖文件转换为:导出一个base64字符串
//url-loaderfunction loader(source){// source:文件内容(图片内容 buffer)// 1. 根据buffer生成一个base64编码// 2. 返回一段代码 export default "base64编码"}
const { CleanWebpackPlugin } = require("clean-webpack-plugin")const HtmlWebpackPlugin = require('html-webpack-plugin');const CopyWebpack = require('copy-webpack-plugin');module.exports = {mode: 'development',plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin()],module: {rules: [{test: /\.(png)|(gif)|(jpeg)$/,use: [{loader: 'url-loader',options: {limit: 1 * 1024 , //默认为fasle,所有的文件你都会被base64编码,超过设置的字节大小则交给file-loader来做,name:"images/[name].[hash:5].[ext]" // 此配置也是给file-loader来用的}}]}]},devServer: {port: 8001,//端口号open: true,//自动打开浏览器窗口index: 'index.html', //默认请求的文件名proxy: {'/api': {target: 'http://open.duyiedu.com', //前面是一个正则,表示只要是包含api的请求路径,前面的主机地址都匹配为http://open.duyiedu.com,例如你访问的是http://localhost:8080/api/student/findAll会被替换成http://open.duyiedu.com/api/student/findAllchangeOrigin: true, //更改请求头中的host,和origin}},stats: {modules: false,//打包的时候,不输出打包modules的日志信息colors: true,//打包输出的日志,颜色区分}}}
7. 解决路径问题
在使用file-loader或url-loader时,可能会遇到一个非常有趣的问题
比如,通过weback打包的目录结构如下:
dist|—— img|—— a.png #file-loader生成的文件|—— scripts|—— main.js #export default "img/a.png"|—— html|—— index.html #<script src="../scripts/main.js" ></script>
这种问题发生的根本原因:模块中的路径来自于某个loader或者plugin,当产生路径时,loader或plugin只有相对于dist的目录的路径,并不知道该路径将在哪个资源中使用,从而无法确定最终的正确路径
面对这样的情况,需要依靠webpack的配置pulicPath来解决
const { CleanWebpackPlugin } = require("clean-webpack-plugin")const HtmlWebpackPlugin = require('html-webpack-plugin');const CopyWebpack = require('copy-webpack-plugin');module.exports = {mode: 'development',output: {filename: 'scripts/[name][chunkhash:2].js',publicPath: '/' //一般会配置为/,根目录,一般情况下没什么用,但是某些插件中会用到,一般用来解决路径问题,所有用到这个路径的都会收到影响},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({template: './public/index.html',filename: 'html/index.html'})],module: {rules: [{test: /\.(png)|(gif)|(jpeg)$/,use: [{loader: 'file-loader',options: {name: "imgs/[name].[hash:5].[ext]",// publicPath: '/files' //这里配置的是单独为loader配置的路径}}]}]},devServer: {port: 8001,//端口号open: true,//自动打开浏览器窗口openPage: 'html/index.html',index: 'index.html', //默认请求的文件名proxy: {'/api': {target: 'http://open.duyiedu.com', //前面是一个正则,表示只要是包含api的请求路径,前面的主机地址都匹配为http://open.duyiedu.com,例如你访问的是http://localhost:8080/api/student/findAll会被替换成http://open.duyiedu.com/api/student/findAllchangeOrigin: true, //更改请求头中的host,和origin}},stats: {modules: false,//打包的时候,不输出打包modules的日志信息colors: true,//打包输出的日志,颜色区分}}}
