自动将代码打包发送到浏览器端,用新的模块替换旧的模块,实现局部更新而不是整体刷新,可以保存应用的状态,提高开发效率。
webpack-dev-server
webpack模块
1、是离散功能块
2、作用:接触面更小,检验调试更容易,使得每个模块都有明确的任务和作用
3、模块化的语句:es2015的import,commonjs的require语句,amd的define和require语句,css
commonjs
是什么:
1、是js模块化规范
流行:
2、得益于nodejs采用这种规范,通过npm发布的很多第三方模块都采用了 commonjs
语法:
3、导入:require(),导出module.exports=modules.fun
缺点
1、无法直接运行在浏览器下
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
module.exports = getClientEnvironment;
AMD
不同
1、采用异步加载依赖模块
优点
1、可以在浏览器和nodejs环境下运行
2、异步并行
es6模块化
缺点
1、需要转换为es5
语法
1、export var s=1 直接在声明之前🏠export
2、export{ s,a,s}一次抛出多个变量,逗号分割
3、as可以重命名
4、import「s」from ‘./one.js’,从文件路径里面引入模块
import {a,b} from './one.js';
import * as num from './one';
console.log(num.a);
console.log(num.b);
export default {
data:{
name:'张三',
age:18,
family:['爸爸','妈妈','爷爷','奶奶']
},
add:function(a,b){
return a+b;
},
addOne:function(arr){
var nArr = [];
for(let i=0;i<arr.length;i++){
nArr.push(arr[i]+1);
}
}
}
这是一段最简单不过的代码了,只抛出了一个默认值,如何引用相信你一定能想到吧
import myFrist from './one';
let arr = [123,54,'er',54,654,321]
console.log(myFirst.addOne(arr));```
```javascript
import React, { Component } from "react";
export default CartoonEdit;
我是同事A
import B from ‘./b.js’;
export default B ;
直接这样就可以,这样你就可以和同事b没有一点联系,却调用了他的方法,同时同事A这边引用了之后就抛出了,B的代码是不会在A代码部分加载的
每个人都得到了自己想要的东西而且还没有多加载代码,这就是模块化神奇的地方。
同时,模块化是ES6新推出的,并不同于其他代码。
import后面的from指定模块文件的位置,可以是相对路径,也可以是绝对路径,.js后缀可以省略。
import命令具有提升效果,会提升到整个模块的头部,首先执行。
import是静态执行,所以不能使用表达式和变量,那些是只有在运行时才能得到结果的语法结构。
比如
if(a === 1){
import one from './one.js';
}//报错,不被允许的写法
构建工具
用处:
源代码转换成发布到线上的可执行 JavaScrip、CSS、HTML 代码
完成
代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等。
文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。
代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
开发语言
nodejs
webpack
优点
缺点
只适用于模块化开发的项目
安装
1、最好安装到本项目,防止版本冲突
打包步骤
1、沿着入口文件递归查找所有导入语句依赖,将入口文件和依赖打包到一个单独输出文件
loader
1、支持非js文件
2、在module.rules数组里面配置规则
resolve
1、用于寻找模块对应的文件
2、alias可以将导入模块里面的component换成指定的路径
3、react
// Webpack alias 配置
resolve:{
alias:{
components: './src/components/'
//可以使得查找文件的时候不用查找这么多文件
‘react’
}
}
module: {
rules: [
{
// 用正则去匹配要用该 loader 转换的 CSS 文件
test: /\.css$/,
use: ['style-loader', 'css-loader?minimize'],
}
]
}
3、use数组的值是一个loader组成的数组,执行顺序是从后往前
4、每一个loader参数可以通过URL、querystring(?)的方法传入参数,还可以使用对象方法:
{
loader:'css-loader',
options:{
minimize:true,
}
5、style-loader的用法:1、用字符串存储css内容。2、执行js时动态往htmlhead标签里添加style标签
plugin
1、把注入到bundlejs里面的css提取到单独文件里面
2、用到插件:extract-text-webpack-plugin
是数组,每一项都是插件的实例
plugins: [
new ExtractTextPlugin({
// 从 .js 文件中提取出来的 .css 文件的名称
filename: `[name]_[contenthash:8].css`,
}),
]
devserver
自动化
1、使用http服务
2、会启动http服务器
3、也会启动webpack
4、接受webpack发出的文件变更信号
5、通过websocket协议自动刷新
启动为npx devserver
开发环境基本配置
处理图片资源
处理其他资源
打包输出目录
生产模式
提取css
css兼容
css压缩
js压缩
html压缩
生产环境配置
原生webpack
2、监听文件变化,自动刷新,实时预览
3、支持source map 方便调试
安装
1、安装webpack-dev-server
2、安装之后执行 webpack-dev-server,就可以启动dev server了。
3、devserver会包打包的文件保存在内存中,访问的时候必须通过http访问
4、实时修改任何一个文件,浏览器会自动刷新
5、开启监听模式,webpack --watch
6、当构建完成之后通知devserver
7、devserver会让webpack在构建出的js代码里面注入代理客户端控制网页,
8、网页和devserver通过websocket通信。
9、但是index.html不会更新,因为只有入口文件和依赖文件相关的文件才会添加到监听列表里面
模块热替换
1、不重新更新页面的时候,用新的页面替换旧的页面。
2、开启模块热替换,启动devserver的时候带上–hot参数
source map
1、启动的时候带上–devtool source -map 然后重启后刷新页面·
核心概念
1、entry
2、output
3、loader
4、plugin
5、mooudle:一个文件就是一个模块
6、chunk,一个chunk由多个模块组合而成,用于代码合并和分割,一个entry和所有依赖的文件被分为一组
7、
配置
entry
output
1、output是一个对象,里面包含一系列配置项
2、只有一个文件filename : 'bundle.js'
3、如果输出多个chunk,就需要借助模版和变量filename : '[name],js'
moudle
1、moudle是一个对象,里面又一个rules数组,数组的每一项都规定了如何处理部分文件
2、三过程:1、条件匹配,三个配置项,test、include、exclude。2、对应规则:use数组配置loader,可以传入参数。3、enforce可以使得顺序放到最前或最后
3、如果loader、里面含有多个参数,需要用对象表示
4、test也可以是数组,里面可以传递多个正则
use:[
{
loader:"css-loader",
options:{
cache:true
},
post是把执行顺序放到最后面
pre是loader执行顺序放到最前面
enforce:'post'
}
]
test:[
/\.jsx?$/,
/\.tsx?$/
],
include:[
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'tests'),
],
exclude:[
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, 'bower_modules'),
]
5、noparse,可以忽略对没采用模块化的文件的递归解析。例如jquery和chartjs
// 使用正则表达式
noParse: /jquery|chartjs/
// 使用函数,从 Webpack 3.0.0 开始支持
noParse: (content)=> {
// content 代表一个模块的文件路径
// 返回 true or false
return /jquery|chartjs/.test(content);
}
5、parse:可以配置那些模块化的语法需要解析。哪些不需要解析
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
parser: {
amd: false, // 禁用 AMD
commonjs: false, // 禁用 CommonJS
system: false, // 禁用 SystemJS
harmony: false, // 禁用 ES6 import/export
requireInclude: false, // 禁用 require.include
requireEnsure: false, // 禁用 require.ensure
requireContext: false, // 禁用 require.context
browserify: false, // 禁用 browserify
requireJs: false, // 禁用 requirejs
}
},
]
}
优化
缩小文件搜索范围
优化loader配置
问题:寻找导入的文件后用loader处理,文件多时会很耗时间,
原因:loader对文件的转换很耗时间
方案:让尽可能少的文件被处理
配置项:test,include,exclude
针对特定目录下的:include:path.resolve(name,‘src’)
优化resolve.modules配置
1、resolve.modules用于配置webpack去哪里寻找第三方模块。
2、先去当前目录的node_moudles寻找,如果没有则去上级
3、当第三方模块都放在项目根目录的时候,就没必要去一层一层的寻找
module.exports = {
resolve: {
// 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
// 其中 __dirname 表示当前工作目录,也就是项目根目录
modules: [path.resolve(__dirname, 'node_modules')]
},
};
使用dllpligin
1、接入动态链接库
2、把基础模块抽离出来,打包到动态链接库里面
3、存在链接库的模块不能再次打包,直接去链接库中获取
4、包括react和react dom都是链接库中的模块
5、使用插件,dllplugin插件,打包出一个个单独的链接库文件
6、dllreferenceplugin插件,在配置文件中引入dllplugin插件打包好的动态链接库文件
7、构建出的目录结构
polyfill,包括promise和fetch等API
react.dll.js里面包含了react的基础运行环境,就是react和react dom模块
其中 polyfill.manifest.json 和 react.manifest.json 文件也是由 DllPlugin 生成出,用于描述动态链接库文件中包含哪些模块,
main.js是执行入口文件,当依赖的模块在dlljs时,就直接通过dlljs文件的全局变量获取模块
配置:
新建一个webpack配置文件webpack-dll.config.js
webpack --config webpack_dll.config.js 命令。
在确保动态链接库存在时,才能正常的编译出入口执行文件。
方法是执行 webpack 命令。这时你会发现构建速度有了非常大的提升。
happy pack
1、webpack单线程,一件挨着一件做
2、同一时刻处理多个任务
3、happypack将任务分解为多个子进程并发执行,子进程处理结束后会发送给主进程
4、不可以多线程,因为js是单线程
one of
1、