一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
webpack可以看作一个模块打包机,它做的事情是,分析你的项目结构,找到javaScript模块以及其他的一些浏览器不能直接运行的扩展语言(Scss,typeScript等),并将其打包为合适的格式以供浏览器使用。 webpack新的版本里有默认的打包方式,但是很弱,只能认js模块,入口文件只认index.js
###webpack配置文件 零配置是很弱的,特定的需求,总是需要自己进行配置 webpack 默认配置文件,叫webpack.config.js,我们可以对文件进行修改,进行个个性化配置 默认的配置文件:webpack.config.js
npx webpack // 执行命令,webpack会找到默认的配置文件
不使用默认配置文件:webpackC.js
npx webpack --config webpackC.js // 指定webpack使用webpackC.js座位配置文件并执行
修改package.json scripts字段:
"script": {
"bundle": "webpack" // 这里就不要添加npx,因为npm run ,会优先使用
}
webpack打包入口参数entry
entry: {
mian: './index.js'
}或
entry: "./index.js",
输出出口output
output: {
publickPath: ''// 公共路径
filename: './build/d.js' // 打包之后的名字
path: path.resolve(__dirname,'./build') ;、\\打包
}
因为webapck默认只能处理js模块,所以如果需要处理其他格式的模块需要下载各种loader postcss-loader
postcss-loader可以补全css3的头
cssloader
'style-loader', 'css-loader', 'postcss-loader'
scssloader
node-sass sass-loader 'style-loader', 'css-loader',
copy-webpack-plugin 作用:在webpack中拷贝文件和文件夹
// 是一个拷贝文件插件
npm install --save-dev copy-webpack-plugin
//
import CopyWebpackPlugin=require('copy-webpack-plugin');
new CopyWebpackPlugin([
{
from: __dirname+'/src/components',
to: __dirname+'/dist',
ignore: ['.*']
}
])
from 定义要拷贝的源文件 from:__dirname+'/src/components'
to 定义要拷贝到的目标文件夹 to: __dirname+'/dist'
toType file 或者 dir 可选,默认是文件
force 强制覆盖前面的插件 可选,默认是文件
context 可选,默认base context可用specific context
flatten 只拷贝指定的文件 可以用模糊匹配
ignore 忽略拷贝指定的文件 可以模糊匹配
###plugin plugin可以在webpack运行到某个阶段的时候,帮你做一些事情,类似生命周期概念扩展插件,在webpack构建过程中的特定时机注入扩展逻辑来改变构建结果或做你想做的事情 HTMLWebpackPlugin HTMLWebpackPlugin 会在打包结束后,自动生成一个html文件,并把打包生成的js模块引入到该html当中 配置:
title: 用来生成页面的 title 元素
filename: 输出的 HTML 文件名,默认是 index.html, 也可以直接配置带有子目录。
template: 模板文件路径,支持加载器,比如 html!./index.html
inject: true | 'head' | 'body' | false ,注入所有的资源到特定的 template 或者 templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body 元素的底部,'head' 将放置到 head 元素中。
favicon: 添加特定的 favicon 路径到输出的 HTML 文件中。
minify: {} | false , 传递 html-minifier 选项给 minify 输出
hash: true | false, 如果为 true, 将添加一个唯一的 webpack 编译 hash 到所有包含的脚本和 CSS 文件,对于解除 cache 很有用。
cache: true | false,如果为 true, 这是默认值,仅仅在文件修改之后才会发布文件。
showErrors: true | false, 如果为 true, 这是默认值,错误信息会写入到 HTML 页面中
chunks: 允许只添加某些块 (比如,仅仅 unit test 块)
chunksSortMode: 允许控制块在添加到页面之前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto'
excludeChunks: 允许跳过某些块,(比如,跳过单元测试的块)
CleanWebpackPlugin 打包之前删除之前build的文件 mini-css-extract-plugin 将CSS提取为独立的文件的插件,对每个包含css的js文件都会创建一个CSS文件,支持按需加载css和sourceMap 只能用在webpack4中
###sourceMap 源代码与打包后的代码的映射关系
在dev模式中,默认开启,关闭的话 可以在配置文件里
devtool:"none"
devtool的介绍:webpack.js.org/configurati…
eval:速度最快,使用eval包裹模块代码,
source-map: 产生.map
文件
cheap:较快,不用管列的信息,也不包含loader的sourcemap
Module:第三方模块,包含loader的sourcemap(比如jsx to js ,babel的sourcemap)
inline: 将.map
作为DataURI嵌入,不单独生成.map
文件
这里的关键子可以组合在一起用
配置推荐:
devtool:"cheap-module-eval-source-map",// 开发环境配置
devtool:"cheap-module-source-map", // 线上生成配置
###WebpackDevServer 提升提升开发效率的利器 每次改完代码都需要重新打包一次,打开浏览器刷新一次,很麻烦,我们可以安装使用WebpackDevServer来改善这块体验. 启动服务后,会发现dist目录没有了,这事因为devSever把打包后的模块不会放到dist目录下,而是放到内存中,从而提升速度,
npm install webpack-dev-server -D
修改下package.json
"scripts": {
"server": "webpack-dev-server"
},
在webpack.config.js配置:
devServer: {
contentBase: "./dist",
open: true,
port: 8081
// 设置代理
proxy: {
"/api": {
target: "http://localhost:9092"
}
}
},
修改webpack.config.js 设置服务器代理
dev-server: {
proxy: {
"/api": {
target: "http://localhost:9092"
}
}
}
###Hot Module Replacement (HMR:热模块替换) 启动hmr
devServer: {
contentBase: "./dist",
open: true,
hot:true,
//即便HMR不生效,浏览器也不自动刷新,就开启hotOnly
hotOnly:true // 设置为false 刷新页面
},
配置文件头部引入webpack
const webpack = require("webpack");
在插件配置处添加:
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "src/index.html"
}),
new webpack.HotModuleReplacementPlugin() // 启动webapck热更新模块
],
处理js模块HMR(不刷新页面更新js)
需要使用module.hot.accept来观察模块更新 从而更新
devServer: {
contentBase: "./dist",
open: true,
hot:true,
//即便HMR不生效,浏览器也不自动刷新,就开启hotOnly
hotOnly:true
},
//index.js
import counter from "./counter";
import number from "./number";
counter();
number();
if (module.hot) { // 判断是否开始了热更新
module.hot.accept("./b", function() { // 不刷新页面的情况 监控模块更新
document.body.removeChild(document.getElementById("number"));
number();
});
}
// HMR 对
###Babel处理ES6 官方网站:babeljs.io/
npm i babel-loader @babel/core @babel/preset-env -D
//babel-loader是webpack 与 babel的通信桥梁,不会做把es6转成es5的工作,这部分工作需要用到@babel/preset-env来做 // babel/core是babel转化的核心库 也不负责转化 //@babel/preset-env里包含了es6转es5的转换规则
//index.js
const arr = [new Promise(() => {}), new Promise(() => {})];
arr.map(item => {
console.log(item);
});
通过上面的几步 还不够,Promise等一些还有转换过来,这时候需要借助@babel/polyfill,把es的新特性都装进来,来弥补低版本浏览器中缺失的特性
@babel/polyfill
npm install --save @babel/polyfill
Webpack.config.js
//在入口文件引入babel/polyfill
import "@babel/polyfill"; // 没有@是babel是babel6 有@的是babel7的特性
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"]
}
}
会发现打包的体积大了很多,这是因为polyfill默认会把所有特性注入进来,假如我想我用到的es6+,才会注入,没用到的不注入,从而减少打包的体积,可不可以呢 当然可以 修改Webpack.config.js
//开启按需加在 就不需要在入口文件引入polyfill了
options: {
presets: [
[
"@babel/preset-env",
{
targets : {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1"
},
useBuiltIns: "usage"//按需注入
}
]
]
}
polyfill 是全局注入,会造成全局变量污染 当我们开发的是组件库,工具库这些场景的时候,polyfill就不适合了,因为polyfill是注入到全局变量,window下的,会污染全局环境,所以推荐闭包方式:@babel/plugin-transform-runtime
写项目用polyfill,写第三方插件用plugin-transform-runtime
@babel/plugin-transform-runtime
plugin-transform-runtime 不会造成全局变量污染 缺点:不会把原型链上的方法转换成polyfill
npm install --save-dev @babel/plugin-transform-runtime
npm install --save-dev @babel/runtime
// babel/runtime需要转换的核心库
npm install --save-dev @babel/runtime-corejs2
options: {
// presets: [
// [
// "@babel/preset-env",
// {
// targets: {
// edge: "17",
// firefox: "60",
// chrome: "67",
// safari: "11.1"
// },
// useBuiltIns: "usage"
// }
// ]
// ]
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 2,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
useBuiltIns选项是babel7的新功能,这个选项告诉babel如何配置polyfill它有三个参数可以使用: 1 entryL需要在webpack的入口文件里import "@babel/polyfill"; babel会根据你的使用情况倒入垫片。没有使用的功能不会被打入相应的垫片 2usage:不需要import,全自动检测,但是要安装@babel/polyfill"(实验阶段) false:如果你imprt "import "@babel/polyfill"它不会排除掉没有使用的方法,程序会很大(不推荐) ###扩展: babelrc文件: 新建.babelrc文件,把options部分移入到该文件中,就可以了
//.babelrc
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 2,
"helpers": true,
"regenerator": true,
"useESModules": false
} ]
] }