什么是 webpack
使用 webpack 作为前端构建工具
- 代码转化:
TypeScript
编译成Javascript
,SCSS
编译成Css
等 - 文件优化:压缩
JavaScript
、Css
、Html
代码 压缩合并图片等 - 代码分割:提取多个页面的公共代码 提取首屏不需要执行部分的代码让其异步加载
- 模块合并:在采用模块化的项目会有很多个模块和文件,需要构建功能把模块分类合并成一个文件
- 自动刷新:监听本地源代码的变化,自动重新构建,刷新浏览器
- 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统
在 webpack 应用中有两个核心
- 模块转换器:用于把模块原内容按照需求转换成新内容,可以加非 JS 模块
- 扩展模块:在 webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做 NIIT 想要的事情
初始化项目
代码语言:javascript复制npm init -y
npm i webpack webpack-cli --save-dev
代码语言:javascript复制npm -S 是--save的缩写 是生产
npm -D 是--save-dev的缩写 是开发
webpack-cli
的目的是解析用户传递一些参数给 webpack 打包
打包
- webpack 默认支持模块的写法
commonJs
规范是 Node - 也支持 es6 规范 esmodule
- 把模块打包,解析出浏览器可以识别的代码
- 装
webpack
的时候是装的开发环境 直接webpack
是找不到的,可以使用npx
(这个命令是 npm 5.2) 之后出来的npx
是默认找node_modules
中的.bin
目录下的文件
npx webpack
- 两种模式:
开发环境
生产环境
npx webpack --mode development 开发环境不会被压缩
为了方便也可以这么写,使用 npm run
命令这个命令执行的时候默认会把 node_modules
的.bin 文件放到全局上,执行之后销毁npm run buildnpm run dev
"scripts": {
"build":"webpack --mode production",
"},
- webpack 配置文件默认叫
webpack.config.js
webpack.file.js
默认导出的是配置文件
- 入口
module.exports={ //入口 entry:path.resolve(__dirname,'./src/index.js'), //写路径都采用绝对路径 }
- 出口
module.exports={ output:{ filename:"bundle.js", path:path.resolve(__dirname,"dist"); } }
- 模式
module.exports = { mode: "development" //当前是开发模式 }
代码语言:javascript复制"scripts": { "build": "webpack", "dev":"webpack" }, //- 变量的形式
webpack.config.js
module.exports = (env)=>{ //env 环境变量 console.log("mode",env) //函数要返回配置文件,没返回会采用默认配置 }
package.json
"scripts": { "build": "webpack --env.production", "dev":"webpack --env.development" },
为了区分开发模式和生产模式 会新建一个 build
文件 新建一个基础配置 webpack.base.js
webpack.base.js webpack.dev.js webpack.prod.js
通过--config 指定执行的文件是哪一个。
- 可以在 base 文件合并
- 可以创建 dev,prod 分别在这两个文件中合并 base
"scripts": {
"build": "webpack --env.production --config ./build/webpack.base.js",
"dev": "webpack --env.development --config ./build/webpack.base.js"
},
- 可以通过 webpack-merge 来合并配置文件
npm i webpack-merge --save-dev
用法
代码语言:javascript复制if(isDev){
return merge(base,dev)
}else{
return merge(base,prod)
}
如果是开发环境,要使用 webpack-dev-server
npm i webpack-dev-server --save-dev
webpack-dev-server 是在内存中打包的不会产生实体
代码语言:javascript复制 "scripts": {
"build": "webpack --env.production --config ./build/webpack.base.js",
"dev": "webpack-dev-server --env.development --config ./build/webpack.base.js"
},
代码语言:javascript复制module.exports={
mode:"development",
devServer:{ //开发服务的配置
port:3000,
compress:true, //gzip 可以提升返回页面的速度
contentBase:path.resolve(__dirname,'../dist') //webpack启动服务会在dist目录下
}
}
- 在 dist 打包自动生成 html 文件并且引入打包后的 js 内容
npm i html-webpack-plugin --save-dev
在根文件下创建 public 文件夹
代码语言:javascript复制 plugins:[
new HtmlWebpackPlugin({
template:path.resolve(__dirname,'../public/index.html'),
filename:"index.html",
minify:!isDev&&{
removeAttributeQuotes:true, //去掉双引号
collapseWhitespace:true //去掉空格
}
})
]
- 每次打包重新生成 dist
npm i clean-webpack-plugin --save-dev
代码语言:javascript复制 //每次打包先清空dist文件夹
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*'] //打包之前清空目录 默认是这个配置 所有目录下的所有文件
}),
代码转化
css
先解析 css
代码语言:javascript复制// index.js
import './index.css'
//引入css
代码语言:javascript复制1.
loader
的执行顺序 默认从下往上执行 从右往左执行2.
css-loader
会解析 css 语法style-loader
会将解析的 css 变成 style 标签插入到页面中3.解析 css 需要两个
css-loader
style-loader
npm i css-loader style-loader --save-dev
代码语言:javascript复制转化什么文件 用什么去转 使用那些loader
loader写法 可以是[] 也可以是{}也可以是""
rules:[
{
test:/.css$/,
use:['style-loader','css-loader']
},
]
预处理器
代码语言:javascript复制
scss
node-sass
sass-loader
npm i node-sass sass-loader --save-dev
代码语言:javascript复制匹配到scss结尾的文件使用sass-loader来调用node-sass处理sass文件
{
test:/.scss$/,
use:['style-loader','css-loader','sass-loader']
}
less
less-loader
stylus
stylus-loader
如果 css 里引入了 scss 文件
代码语言:javascript复制rules:[
{
test:/.css$/,
use:['style-loader',{
loader:'css-loader',
options:{
importLoaders:1
}
},'sass-loader']
},
]
css 加前缀
- 自动加前缀
npm i postcss-loader --save-dev
npm i autoprefixer --save-dev
需要一个配置文件 post.config.js
module.exports={
plugins:[
require("autoprefixer")
]
}
创建一个.browserslistrc
文件
cover 95%
- 这么写开发是 ok 的,但是怎么解决生产样式?
- 解析 css 的时候就不能渲染 dom
- 希望 css 可以和 js 一起加载
mini-css-extract-plugin
需要把 css 抽离
npm i mini-css-extract-plugin --save-dev
代码语言:javascript复制new MiniCssExtractPlugin({ //如果是开发模式就不要用抽离样式的插件
filename:"css/main.css"
})
代码语言:javascript复制{
test: /.css$/,
use: [
isDev?'style-loader':MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2
}
}, 'postcss-loader', 'sass-loader']
}
webpack.prod.js
代码语言:javascript复制const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
module.exports={
mode:"production",
optimization: { //优化项
minimizer:[ //可以放置压缩方案
new OptimizeCSSAssetsPlugin(), //用了这个 js也得手动压缩
new TerserJSPlugin()
]
},
}
图片
- 压缩图片
npm i file-loader --save-dev
npm i url-loader --save-dev
代码语言:javascript复制{
test:/.(woff|ttf|eot|svg)/,
use:"file-loader"
},
{
test: /.(jpe?g|png|gif|jpg)$/,
use: {
loader: "url-loader",
//如果大于100k的图片继续使用file-loader
options: {
name: 'image/[contentHash].[ext]',
limit: 100 * 1024
}
}
//file-loader 默认的功能是拷贝的功能
//我希望是当前比较小的转化成base64 比以前大 好处就是不用发http请求
}
js
es6
转es5
但是有些 api 不是 es6 语法比如装饰器 类的属性- babel 转化功能 vue-cli 基于 babel6 来实现的,但是现在最新 babel 是 babel7
- @babel/core 核心模块
- @babel/preset-env 把 es6 转化成 es5
- babel-loader 是 babel 和 webpack 的桥梁
代码语言:javascript复制总结:默认会调用
@babel/core
来转化代码 转化的时候用@babel/preset-env
将 es6 转化成 es5
{ //解析js文件 调用@babel/core
test:/.js$/,
use:"babel-loader"
},
- 创建
.babelrc
文件默认是 options 的配置
{
"presets:[
"@babel/preset-env" //从下到上执行 这个是插件包
],
"plugins":[ //从上到下执行 这个是单个插件
]
}
- 解析提案语法 类的属性
npm i @babel/plugin-proposal-class-properties -D
代码语言:javascript复制"plugins":[ //从上到下执行
["@babel/plugin-proposal-class-properties",{"loose":true}]
]
loose:true
表示宽松 this.a=1loose:false
Object.definedProperty
解析装饰器
代码语言:javascript复制npm i @babel/plugin-proposal-decorators --save-dev
- 必须在
@babel/plugin-proposal-class-properties
上面执行
"plugins":[ //从上到下执行
["@babel/plugin-proposal-decorators",{"legacy":true}],
["@babel/plugin-proposal-class-properties",{"loose":true}]
]
- 解析高级语法 使用的 api 自动转化 并且是按需加载
"presets":[
["@babel/preset-env",{
"usageBuitIns":"usage" //按需加载
}] //从下到上执行
],
- 节约代码大小
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
解析jsx
代码语言:javascript复制npm i @babel/preset-react --save-dev
解析ts
ts-loader
使用typescript
库- babel7 @babel/preset-typescript 和 typescript 库没有关系
npm i typescript
npx typescript -init 生成一个typescript文件
解析vue
vue.shims.d.ts
declare module "*.vue"{
import Vue from "vue";
export default Vue
}
代码语言:javascript复制npm i vue-loader vue-template-compiler -D
代码语言:javascript复制{
test:/.vue$/,
use:"vue-loader"
},
const VueLoaderPlugin = require("vue-loader/lib/plugin");
new VueLoaderPlugin(),
vue
写ts
npm i vue-property-decorator --save-dev
代码语言:javascript复制["@babel/preset-typescript",{
"allExtensions":true
}]
最后
了解了上面的这些webpack,基本上就可以搭建我们的开发环境了,本文结束,有什么问题和有错误的地方,欢迎大家的留言和评论,还有后续更新,下期更加精彩