接上篇loader继续 这次是plugin
LIST
- HtmlWebpackPlugin
- clean-webpack-plugin
- ExtractTextWebpackPluginr
- sourceMap
- WebpackDevServer
- 解决开发阶段本地请求跨域
- Babel处理ES6
- 配置React打包环境
HtmlWebpackPlugin
htmlwebpackplugin会在打包结束后,自动生成一个html文件,并把打包生成的js模块引入到该html中。
npm install --save-dev html-webpack-plugin安装
// 修改webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
// filename: 'index_min.html' // 编译之后的文件名
template: './index.html' //设置以哪个文件为模板
})
]
...
}
clean-webpack-plugin
clean-webpack-plugin打包前自动清空dist目录
npm install --save-dev clean-webpack-plugin
// 修改webpack.config.js
const cleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
// filename: 'index_min.html'
template: './index.html'
}),
new cleanWebpackPlugin()
],
...
}
ExtractTextWebpackPlugin
ExtractTextWebpackPlugin 会将css、less、sass文件打包成单独的文件 用link标签方式引入到html中 会将css文件都合并到一个文件中 less文件合并到一个文件中npm install --save-dev extract-text-webpack-plugin@next安装一个最新版本 现在这个插件的3版本的 有用的API已经废弃
// 修改webpack.config.js
// 创建多个实例 因为我们的案例里既有css 又有less
const extractCSS = new ExtractTextPlugin('stylesheets/[name]-css.css');
const extractLESS = new ExtractTextPlugin('stylesheets/[name]-less.css');
module.exports = {
...
plugins: [
...
extractCSS,
extractLESS
],
module: {
rules: [
...
{
test: /\.css$/,
use: extractCSS.extract(['css-loader', 'postcss-loader']),
},
{
test: /\.less$/,
use: extractLESS.extract(['css-loader', 'postcss-loader', 'less-loader']),
}
]
}
}
...
}
// 我们再创建个css文件 在index.js中引用 然后进行编译 会发现生成了两个css文件 一个是css后缀打包的文件,一个是less后缀打包的文件 也就是说我们在index.js引入的两个css后缀的文件被放到了一个文件中
打包后的文件
打包前的css文件
sourceMap
源代码与打包后的代码的映射关系 可以看到具体的报错和输出位置在哪个文件哪一行
首先我们在配置文件中生命mode: 'development',这样可以便于debug
在dev模式中,默认开启,关闭的话 可以在配置里件devtool:"none"
eval:速度最快
cheap:较快,不用管列的报错
Module:第三方模块
开发环境推荐:
devtool:"cheap-module-eval-source-map"
线上环境可以不开启:如果要看到一些错误信息,推荐;
devtool:"cheap-module-source-map"
WebpackDevServer
提升开发效率的利器
每次改完代码都需要重新打包一次,打开浏览器,刷新一次,很麻烦
我们可以安装使用webpackdevserver来改善这块的体验
npm install webpack-dev-server -D安装
修改下package.json 加个启动命令
"scripts": {
"server": "webpack-dev-server"
},
在webpack.config.js配置:
devServer: {
contentBase: "./dist", // 把服务器启动在dist文件下
open: true, // 自动打开浏览器
port: 8081 // 端口号
},
使用npm run server启动
启动服务后,会发现dist目录没有文件,这是因为devServer把打包后的模块不会放在dist目录下,而是放在到内存中,从而提升速度
解决开发阶段本地请求跨域
先来创建一个跨域环境,用express模拟一个后端api接口
// npm i express -D
// 创建server.js
const express = require('express')
const app = express()
app.get('/api/info', (req, res) => {
res.json({
content: '测试跨域请求'
})
})
app.listen('9092')
// node server.js
然后在index.js中请求该接口
import axios from 'axios'
axios.get('http://localhost:9092/api/info').then(res=>{
console.log(res)
})
我们可以看到结果实际上是跨域了 在正式环境我们会用cors或者nginx代理,在开发环境webpack-dev-server也提供了代理功能,可以做代理处理
// 修改webpack.config.js
devServer: {
...
proxy: {
"/api": {
target: "http://localhost:9092"
}
}
},
// 修改index.js 去掉协议
import axios from 'axios'
axios.get('api/info').then(res=>{
console.log(res)
})
这样请求就可以正常过来了
Babel处理ES6
官方链接babeljs.io/
npm i babel-loader @babel/core @babel/preset-env -D安装
babel-loader是webpack与babel的通信桥梁,不会做把es6转成es5的工作,这部分工作需要用到@babel/preset-env来做,@babel/preset-env里包含了es6转es5的转换规则
// 在index.js中加一些es6语法
const arr = [new Promise((resolve) => { resolve(1) }), new Promise((resolve) => { resolve(1) })]
然后我们使用npx webpack编译,这里是为了看下编译后的文件,就没采用webpack-dev-server去做编译。
我们可以看到build.js文件中编译的结果,const ()=>{}都得到了编译,但是promise并没有编译
所以上面这步还不够,Promise等一些还有转换过来,这时候需要借助@babel/polyfill,把es的新特性都装进来,来弥补低版本浏览器中缺失的特性
npm install --save @babel/polyfill安装
// index.js最上方引入@babel/polyfill
import "@babel/polyfill";
我们再进行编译
我们对比之前的文件,发现整体文件大了好多,,这是因为polyfill默认会把所有特性注入进来
所以我们考虑按需引入
// 去掉index.js中的引用
// 修改配置 webpack.config.js
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: "usage", //按需注入
corejs: 3
}
]
]
}
}
打包后明显小了很多
当我们开发的是组件库,工具库这些场景的时候,polyfill就不适合 ,因为polyfill是注入到全局变量, window下的,会污染全局环境,所以推荐闭包方式:@babel/plugin-transform-runtime
// 安装
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
// 修改配置
// presets: [
// [
// '@babel/preset-env',
// {
// useBuiltIns: "usage", //按需注入
// corejs: 3
// }
// ]
// ]
plugins: [
[
"@babel/plugin-transform-runtime",
{
"corejs": 2,
}
]
]
.babelrc文件,就是将options里的内容移到外面来
配置React打包环境
npm install react react-dom --save安装
// 我们创建一个react.js用import或require把这个文件引入到index.js中
// react.js
import React, { Component } from "react";
import ReactDom from "react-dom";
class App extends Component {
render() {
return <div>hello world</div>;
}
}
ReactDom.render(<App />, document.getElementById("app"));
安装babel与react转换的插件:
npm install --save-dev @babel/preset-react
然后修改配置文件
// webpack.config.js
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: "usage", //按需注入
corejs: 3
},
],
"@babel/preset-react"
]
// plugins: [
// [
// "@babel/plugin-transform-runtime",
// {
// "corejs": 2,
// }
// ]
// ]
}
}
然后进行编译,打开页面可以看到我们的react组件可以正常显示