D环境参数:
node:10版本以上(10.4.0) 这里有个坑:10.4.0版本才开始支持BigInt对象
webpack:4.26版本以上(4.44.1)
webpack是什么:
webpack是一种前端资源构建工具,一个静态模块打包器(module bundler)
在webpack看来,前端的所有资源文件(js、json、css、img、less……)都可以作为模块处理
它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)
webpack的五个核心概念:
entry:入口指示 webpack以哪个文件为入口起点开始打包,分析构建内部依赖图
output:输出指示 webpack打包后的资源 bundles输出到哪里去,以及如何命名
loader:让webpack能够去处理那些非JavaScript文件(webpack自身只理解JavaScript)
plugins:插件可以用于执行范围更广的任务。插件的范围包括从打包优化和压缩,一直到重新定义环境中的变量等
mode:指示webpack使用响应模式的配置
选项 | 描述 | 特点 |
development |
将process.env.NODE_ENV的值设置为development 启用NamedChunksPlugin和NamedModulesPlugin |
能让代码本地调试运行的环境 |
production |
将process.env.NODE_ENV的值设置为production 启用FlagDependencyUsagePlugin、 FlagIncludedChunksPlugin、 ModuleConcatenationPlugin、 NoEmitOnErrorsPlugin、 OccurrenceOrderPlugin、 SideEffectsFlagPlugin、 UglifyJsPlugin |
能让代码优化上线运行的环境 |
webpack实践一下:
这里装全局webpack和webpack-cli的时候,不加版本号时安装的webpack版本是5.4.0,webpack-cli版本是4.2.0。后续会有一些版本冲突,这里安装的时候加上版本号:
npm i webpack@4.41.6 webpack-cli@3.3.11 -g
npm i webpack@4.41.6 webpack-cli@3.3.11 -D
运行指令:
1、开发环境:webpack ./src/index.js -o ./build --mode=development
以 ./src/index.js 文件为入口文件开始打包,打包后输出到 ./build 文件夹下新建 main.js文件,整体打包环境是开发环境
2、生产环境:webpack ./src/index.js -o ./build --mode=production
以 ./src/index.js 文件为入口文件开始打包,打包后输出到 ./build 文件夹下新建 main.js文件,整体打包环境是生产环境
注意:
1、webpack可以处理js和json文件,但是不能处理css和img等文件
2、生产环境和开发环境都可以将ES6的模块化编译成浏览器可以识别的模块化进行读取
3、生产环境比开发环境压缩过的代码看着舒服一点,多一个压缩js代码
使用webpack打包css资源:
1、在 03webpack打包样式资源 目录下创建src目录,分别创建index.js和index.css
index.css中写一点简单的样式:
body{ background-color: red; }
index.js中引入index.css:
// 引入样式资源 import './index.css'
2、根目录下创建webpack.config.js文件,这是webpack的配置文件,指示webpack干哪些活,运行webpack指令的时候,会加载里面的配置:
所有的构建工具都基于nodejs,模块化默认采用commonJS
node找包的特点是当前目录找不到就前往上一级目录找包
所以在webpack01目录下:
npm init -y
npm i webpack webpack-cli -D
npm i css-loader style-loader -D
const { resolve } = require('path') // resolve用来拼接绝对路径 module.exports = { entry: './src/index.js', // 入口文件 // 输出 output: { path: resolve(__dirname, 'build'), // 输出路径 __dirname:nodejs的变量,表示当前文件目录的绝对路径:03webpack打包样式资源/build filename: 'built.js' // 输出文件名 }, // loader的配置 module: { rules: [ // 详细的loader配置,不同文件配置不同的loader处理 { test: /.css$/, // 匹配css文件 use: ['style-loader', 'css-loader'] // use数组中的loader执行顺序:从下到上,从右到左 style-loader:创建style标签,将js中的样式资源插入运行,添加到head中生效 css-loader:将css文件转为commonJS模块加载到js中,里面的内容是样式字符串 } ] }, plugins: [], // plugins的配置 mode: 'development' // 开发模式 // mode:'production' // 生产模式 }
3、运行webpack指令,成功后会生成built.js文件
4、在build文件夹下新建index.html,将built.js文件引入,发现css文件已生效,css文件,style-loader会将js中的样式资源插入运行,添加到head中生效:
如果需要打包less文件(sass文件同理):
1、rules中添加一个解析less的对象:
{ test: /.less/, // 匹配less文件 use: ['style-loader', 'css-loader', 'less-loader'] // less-loader:将less文件转为css文件,需要下载less-loader和less }
2、回到上一级目录下载less-loader和less插件:
npm i less-loader less -D
打包html文件:
1、04webpack打包html资源 文件夹下创建src/index.js和index.html,随便写点内容:
2、根目录下创建webpack.config.js,如果实例化只写new HtmlWebpackPlugin()创建出来的html文件是空的:
const { resolve } = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') // loader下载后可以直接使用,plugins下载后要在这里引入后才能使用 module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [] }, plugins: [ // new HtmlWebpackPlugin() // 默认会创建一个空的html文件,自动引入打包输出的所有资源(js、css) new HtmlWebpackPlugin({ template: './src/index.html' }) // 以 ./src/index.html 为模板,创建一个有结构的html文件,自动引入打包输出的所有资源(js、css) ], mode: 'development' }
3、执行webpack,会在根目录下创建build文件夹,里面有index.html和built.js文件,此处的html是以 ./src/index.html 文件为模板创建的,但是这里会自动将js文件引入
注意:
报错:TypeError: Cannot read property 'tap' of undefined
将版本回退到3.2.0,还是报错:TypeError: Cannot add property htmlWebpackPluginAlterChunks, object is not extensible
npm i html-webpack-plugin@next -D后,成功:(因为之前安装webpack和webpack-cli的时候是最新版本,没有加版本号,加上版本号之后就好了)
打包图片资源:
下载插件:npm i url-loader file-loader html-loader -D
webpack.config.js:
const { resolve } = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'index.js', path: resolve(__dirname, 'build'), publicPath: './' // 解决报错:Automatic publicPath is not supported in this browser }, module: { rules: [ { test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader'] // less-loader负责将less转为css,css-loader负责将css整合到js中,style-loader负责从js中找到css代码创建style标签插入到head中 }, { test: /.(jpg|png|jif)$/, // 这种方式可以处理css中的背景图,但是处理不了html中的img中图片 loader: 'url-loader', // 只有一个loader不用写use,使用url-loader需要下载url-loader和file-loader(前者依赖于后者) options: { limit: 6 * 1204, // 图片大小小于6kb,就会被base64处理 优:减少请求次数,减轻服务器压力 缺:图片体积会更大,文件请求速度更慢 综合来看,将需要转为base64格式的图片的大小限制一下,减少了多次请求,同时控制base64编码长度 esModule: false, // 关闭ES6的模块化,使用commonJS解析(url-loader默认使用ES6模块化解析,html-loader使用commonJS解析,会出现问题) name: '[hash:10].[ext]' // 给图片重命名,[hash:10]:取图片hash值的前10位 [ext]:取文件原来的扩展名 } }, { test: /.html$/, loader: 'html-loader' // 处理html中的img,负责引入img,从而能被url-loader处理 } ] }, plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })], mode: 'development' }
注意:
1、url-loader处理样式中的图片,html-loader处理html中的图片,url-loader依赖于file-loader
2、webpack在解析的时候发现使用了同一个文件,不会重复打包,只会输出一次----即使是在样式和html都使用了同一张图片,webpack在打包的时候只会生成一张图片
3、使用多个loader时使用use数组,它的执行顺序是从右到左,从下到上;如果只使用一个loader,可以使用loader后面跟对应的插件
4、options中的参数:limit可以设置将小于多少k的图片用base64处理,减少请求次数的同时也兼顾base64编码的长度;esModule设置为false,关闭es模块化,使用commonJS的模块化;name图片重命名
webpack打包其他资源(file-loader):
1、src下新建index.html和index.js,将font文件夹准备好
2、webpack.config.js:
const { resolve } = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /.css$/, use: ['style-loader', 'css-loader'] }, { exclude: /.(css|less|html|js)/, // 排除 css|less|html|js 这些资源 loader: 'file-loader', // 打包其他资源用file-loader插件 options: { name: '[hash:10].[ext]' } } ] }, plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })], mode: 'development' // mode: 'production' }
3、webpack命令打包后生成build文件夹,index.html已经将built.js引入,即引入了iconfont.css:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>webpack打包其他资源</title> <script defer src="built.js"></script></head> <body> <span class="iconfont icon-wode"></span> <span class="iconfont icon-suosou"></span> <span class="iconfont icon-below-s"></span> <span class="iconfont icon-dianying"></span> <span class="iconfont icon-yingyuan"></span> <span class="iconfont icon-zuojiantou"></span> </body> </html>
devServer:
在实际开发中经常要修改页面或者参数,不能每次修改一次都执行一次webpack吧,所以就有了devServer,它就是开发服务器。
使用前先安装插件:npm i webpack-dev-server -D
const { resolve } = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [] }, plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })], mode: 'development', /* 开发服务器:devServer,用来自动化-自动编译,自动打开浏览器,自动刷新浏览器 特点:只会在内存中编译打包,不会有任何输出,没有build文件夹 指令:npx webpack-dev-server */ devServer: { contentBase: resolve(__dirname, 'build'), // 项目构建后路径 compress: true, // 启动gzip压缩 port: 3000, // 端口号 open: true // 自动打开浏览器 } }
注意:
在前面安装html-webpack-plugin的时候,因为无法执行webpack命令,直到运行 npm i html-webpack-plugin@next -D 将该插件的版本改为
才运行成功,但是这里的版本对webpack-dev-server的使用有版本冲突,所以将html-webpack-plugin卸载重装
这样就可以正常运行npx webpack-dev-server了。
综上:在使用html-webpack-plugin插件时,它的版本选择如下:(如果前面安装webpack和webpack-cli的时候加上版本号,这里直接npm i html-webpack-plugin -D这两个命令就都可以执行)
如果要使用webpack命令,请安装 npm i html-webpack-plugin@next -D
如果要使用npx webpack-dev-server命令,请安装npm i html-webpack-plugin -D
webpack开发环境基本配置:
const { resolve } = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build'), publicPath: './' }, module: { rules: [ { test: /.css$/, use: ['style-loader', 'css-loader'] }, { test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, { test: /.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 6 * 1024, esModule: false, name: '[hash:10].[ext]', outputPath: 'images' } }, { test: /.html$/, loader: 'html-loader' }, { exclude: /.(html|css|less|js|jpg|png|gif)/, loader: 'file-loader', options: { name: '[hash:10].[ext]', outputPath: 'font' } } ] }, plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })], mode: 'development', devServer: { contentBase: resolve(__dirname, 'build'), compress: true, port: 3000, // open: true } }
所需插件:
{ "name": "webpack01", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^3.4.2", "file-loader": "^6.2.0", "html-loader": "^1.3.2", "html-webpack-plugin": "^4.5.0", "less": "^3.12.2", "less-loader": "^7.0.2", "style-loader": "^2.0.0", "url-loader": "^4.1.1", "webpack": "^4.41.6", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.11.0" }, "dependencies": {} }
打包后的资源目录: