模块化开发
ES Modules特性
通过给script添加type=module的属性,就可以以ES Module的标准执行其中的JS代码。
1.EMS自动采用严格模式,忽略use strict
2.每个ES Module都是运行在单独的私有作用域中
3.EMS是通过CORS的方式请求外部js模块的
4.EMS的script标签会延迟执行脚本
导入与导出
const foo='es modules'
export{foo}
import{foo} from './module.js'
console.log(foo)
ES Modules in Node.js支持情况
在Node环境中直接使用:
node --experimental=modules index.mjs
webpack打包
webpack的基础操作
1.初始化 yarn init --yes
2.安装 yarn add webpack webpack-cli --dev
3.打包 yarn webpack
(简便操作:在package.json文件中,添加"scripts":{"bulid":"webpack"})
配置文件
在根目录下创建webpack.config.js文件
设置入口文件:例如
module.exports={
entry:'./src/main.js'
output:{
filename:'bulid.js'
}//输出文件
}
官方文档:qwbpack.js.org/configurati…
优化:
开发模式命令:yarn webpack --mode development
最原始: yarn webpack --mode none(不做任何处理)
也可以在配置文件中添加新属性:mode:'development'
最后直接执行yarn webpack命令
资源模块的加载
loader可以加载任何类型资源
webpack默认只加载js文件,需要加载其他文件就需要下载相应工具
如css文件:
1.安装 yarn add css-loader --dev
2.安装 yarn add style-loader --dev将css-loader转化的结果以style标签的形式添加到页面上
2.在配置文件中添加属性
module:{
rules:[//加载规则,每个规则需要加载两个属性
{
text:/.css$/, 正则表达式,以.css结尾
use:[//多个属性从后往前执行
'style-loader',
'css-loader'
] 匹配的属性需要的loader
}
]
}
3.运行打包文件 yarn webpack
注意,此文件的入口文件要更改为当前文件,若为js文件,则在js中引入该文件,
import './heading.css'
在导出文件中添加
element.classList.add('heading')
文件加载
首先导入该文件然后下载
yarn add file-loader --dev
与css加载类似,不过需要在output中添加如publicPath:'dist/'
Data URL(小文件推荐)
yarn add url-loader --de
可以限制大小,如在当前use中添加一个options对象
use:{
loader:'url-loader',
options:{
limit:10*1024//限制文件大小为10kb以内
}
}
在使用此资源时需要下载file-loader,因为当大小超过设置的大小范围时要自动加载file-loader。
webpack与ES2015
webpack在处理es6时需要考虑兼容性
办法:下载babel-loader
yarn add babel-loader @babel/core @babel/preset-env --dev
配置相应规则
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
如果需要支持部分标签属性如a标签则
options:{
attrs:['img:src','a:href']//其中第一个是默认值,可以不写
}
webpack插件
自动清理目录插件
clean-webpack-pluging
1.先安装
yarn add clean-webpack-plugin --dev
2.导入插件
const{clean-webpack-plugin}=require clean-webpack-plugin
3.配置属性
plugins:[ new CleanWebpackPlugin() ]
html插件
与上类似,如果需要进行修改可在配置文件其中添加相应的内容如
plugins:[
new HtmlWebpackPlugin({
title:'sfgd',
meta:{
viewport:'width-device-width'
},
})
]
如果需要创建多个html文件,则需要在对于位置多添相应数目的实例
copy-webpack-plugin
将一些静态文件一并打包到相应目录
1.下载安装
2.导入
3.添加实例
new Copy-Webpack-Plugin([
'public'
])
webpack自动编译
监听模式(实时即手动刷新)
yarn webpack --watch
browser-sync dist --files "**/*"(先下载,然后是自动刷新浏览器)
Webpack Dev Server
下载安装:yarn add webpack-dev-server --dev (-- open参数为自动打开浏览器)
Webpack Dev Server代理API
在配置文件中添加:
devServer:{
proxy:{
'/api':{
target:'https://api.github.com'(代理目标),
pathRewritr:{
'^/api':''
};
changeOrigin:true
}
}
}
Source Map配置
在配置文件中:
devtool:'source-map'
HMR
集成于webpack-dev-server中
开启HMR:webpack-dev-server --hot
或者在配置文件中:
const webpack=require('webpack')
devServer:{
hot:true
}
在配置插件处:
plugins:[
new webpack.HotModuleReplacementPlugin()
]
webpack js 以及图片热替换
需要处理HMR
如:
let lastEditor=editor
modulehot.accept('./editor',()=>{
const value=lastEditor.innerHTML
document.body.removeChild(lastEditor)
newEditorinnerHTML=value
document.body.appendChild(newEditor)
lastEditor=newEditor
})
处理图片:
module.hot.accept('./better.png',()=>{
img.src=background//改变路径
})
不同环境下的配置
在配置文件中:
中小项目
module.exports=(env,argv)=>{
const config={
开发环境下的配置
}
if(env==='production'){
config.mode='production'
config.devtool=false
config.plugins=[
...config.plugins
new CleanWebpackPulgin(),
new CopyWenpackPlugin(['pulic'])
]
}
}
大项目
安装:yarn add wenpack-merge --dev
载入模块
mode:exports=merge(common,{
mode:'production',
pulgins:[
new CleanWebpackPulgin(),
new CopyWenpackPlugin(['pulic'])
]
})
运行:yarn webpack --config webpack.prod.js(后面是运行文件名) 也可将此命令放入package.json中
"scripts":{
"bulid":"webpack --config webpack.prod.js"
}
使用Tree Shaking
在配置文件中;
optimization:{
usedExports:true,//找出未被应用的语句
minimize:true//摇掉这些语句
}
如果需要代码合并则添加concatenateModules:true
Tree Shaking与Babel冲突
Tree haking前提是ES Mosules 而Babel不是
解决:
在当前babel的配置中做出修改
presents:[
['@babel/preset-env',{modules:false}]
]
代码分割
多入口打包
在配置文件中
将输出文件动态输出
output:{
filename:'[name].bundle.js'
}
在插件中(plugins)
对html插件中添加
chunks:['当前文件名']
对公共模块进行提取
在配置文件中
optimization:{
splitChunks:{
chunks:'all'
}
}
动态载入(按需加载)
通过import函数导入
import('./album/album').then(({default:album})=>{
mainElement.appendChild(album())
})