目前统一成ES Modules 和 CommonJs,ES Modules是2014年(随着ES2015一起)才出现的标准
//----------
//方式一
export var name = 'foo modules'
//-------
//方式二
var name = 'foo modules'
var age = 25
export { name, age }
export { name as fooname, age} //将name重命名为fooname
export { name as defaule, age} // 将name定义为默认成员
//---------
import './modules.js' //只加载和执行模块,并不提取模块
6、 导出对象中的所有成员import * as mod from './modules.js' //导出模块中的所有成员并作为mod对象的属性
7、import只能出现在最外层作用域,不能嵌套,可以使用import()函数//方式1
import { name, age, defaule as title } from './modules.js'
//方式2
import title, { name, age } from './modules.js'
import { name, age, defaule as title } from './modules.js'
//替换为
export { name, age, defaule as title } from './modules.js'
// 直接导出这个文件中导入的成员,在这个文件中就不能使用这个导入的成员了,可以用来组合一些组件
Webpack配置文件
const path = require('path')
module.export = {
mode: 'development', //webpack的工作模式
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname,'output'),
pubilcPath: 'dist/'
}
module: {
rules: [
{
test: /.js$/,
use: {
loader: 'babel-loader',
options :{
presets: ['@babel/preset-env']
}
}
}
{
test: /.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /.png$/,
use: {
loader: 'url-loader',
options: {
limit: 10 * 1024 //10kb
}
}
},
{
test: /.html$/,
use: {
loader: 'html-loader',
options: {
attrs: ['img:src','a:href']
}
}
}
]
}
}
打包结果的运行原理
+
webpack 资源模块加载
Webpack导入资源模块
Webpack 文件资源加载器
Webpack url加载器
Webpack 常用加载器分类
Webpack 与 ES 2015
webpack 加载资源的方式
Webpack 核心工作原理
开发一个loader
Webpack插件机制
增强webpack在项目自动化方面的能力,解决除了资源加载外的自动化工作,如清除dist目录、拷贝不需要参与打包的资源目录、压缩打包结果的输出代码。
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
plugins: {
new CleanWebpackPlugin(),
//用于生成index.html
new HtmlWebpackPlugin({
title: 'Webpack Plugin Sample',
meta: {
viewport: 'width=device-width'
},
template: './src/index.html'
}),
//生成about.html
new HtmlWebpackPlugin({
filename: 'about.html'
}),
new CopyWebpackPlugin([
'public'
]) //将public目录中的所有文件拷贝到输出目录,上线前再使用
}
}
开发一个插件
webpack采用钩子机制,在webpack工作的环节中都埋下了钩子,通过往不同环节中挂载任务就可以扩展webpack 功能。
//清除webpack打包生成文件中没有用的注释
class MyPlugin{
apply(compiler) {
compiler.hooks.emit.tap('MyPlugin', compilation => {
//compilation打包的上下文
for (const name in compilation.assets){
if(name.endWith('.js')){
const contents = compilation.assets[name].source()
const withoutComments = contents.replace(/\/\*\*+\*\//g, '')
compilation.assets[name] = {
source: () => withoutComments,
size: () => withoutComments.length
}
}
}
})
}
}
Webpack 开发体验问题
yarn webpack --watch
yarn add webpack-dev-server --dev
yarn webpack-dev-server --open
//webpack配置文件中配置如下,可以访问public中的静态文件
devServer: {
contentBase:['public'],
proxy:{
'/api': {
targer: 'https://api.github.com',
pathRewrite: {
'^/api':''
},
// 不能使用localhost:8080作为请求GitHub的主机名
changeOrigin: true
}
}
}
// webpack配置文件中设置如下
devtool: 'source-map'
Webpack 自动刷新问题
const webpack = require('webpack')
//webpack配置文件中
devServer: {
hotOnly: true
}
plugins: [
new webpack.HotModuleReplacementPlugin()
]
// 入口文件中
module.hot.accept('js文件路径', () => {
//当js文件更新后在这里手动处理热替换逻辑
})
webpack 生产环境优化
module.exports = (env, argv) => {
const config = {...}
if (env === 'production') {
config.mode = 'production'
config.devtool = false
config.plugins = [
...config.plugins,
new CleanWebpackPlugin(),
new CopyWebpackPlugin(['plubic'])
]
}
return config
}
//使用webpack-merge合并配置文件,使用yarn add webpack-merge --dev 安装
const common = require('./webpack.common')
const merge = require('webpack-merge')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = merge(common, {
mode: 'production',
plugins: [
new CleanWebpackPlugin(),
new CopyWebpackPlugin(['public'])
]
})
Webpack DefinePlugin:可以手动写入打包后代码中的部分值
const webpack = require('webpack')
module.exports = {
mode: 'none',
entry: './src/main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.DefinePlugin({
// API_BASE_URL: '"https://api.example.com"'
API_BASE_URL:JSON.stringify('https://api.example.com')
})
]
}
Webpack Tree-shaking:检测代码中未引用的代码并去除它们,在生产模式线下自动开启。是webpack一组功能搭配使用的效果。
//集中配置webpack内部优化功能
optimization:{
sideEffects: true //
usedExports: true //在输出结果中只导出外部使用过的成员
concatenateModules: true // 尽可能将所有模块合并到一起并输出到一个函数中,提升效率减小体积,webpack3中的特性
minimize: true // 压缩输出后的代码
}
sideEffects
Webpack 代码分割/分包
const path = require('path')
module.export = {
mode: 'development', //webpack的工作模式
entry: {
index:'./src/index.js',
album:'./src/about.js' //配置多个打包入口
},
output: {
filename: '[name].bundle.js',
path: path.join(__dirname,'output'),
publicPath: 'dist/'
},
optimization: {
splitChunks: {
chunks: 'all' //将所有的公共模块都提取到单独的bundle中
}
}
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options :{
presets: ['@babel/preset-env']
}
}
}
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.png$/,
use: {
loader: 'url-loader',
options: {
limit: 10 * 1024 //10kb
}
}
},
{
test: /\.html$/,
use: {
loader: 'html-loader',
options: {
attrs: ['img:src','a:href']
}
}
}
]
}
plugins: {
new CleanWebpackPlugin(),
//用于生成index.html
new HtmlWebpackPlugin({
title: 'Webpack Plugin Sample',
meta: {
viewport: 'width=device-width'
},
template: './src/index.html',
chunks: ['index']
}),
//生成about.html
new HtmlWebpackPlugin({
filename: 'about.html',
chunks: ['about']
}),
new CopyWebpackPlugin([
'public'
]) //将public目录中的所有文件拷贝到输出目录,上线前再使用
}
}
MiniCssExtractPlugin:实现css的按需加载
OptimizeCssAssetsWebpackPlugin:压缩样式文件
输出文件名Hash
filename: '[name]-[hash].bundle.css' //每次打包所有文件名都会改变
filename: '[name]-[chunkhash].bundle.css' //修改的文件的同一路chunk文件名都会改变
filename: '[name]-[contenthash:8].bundle.css' // 只更新变化的文件的hash名,通过冒号加数字指定hash的长度
Rollup 打包器 和Parcel打包器也可了解
yarn add eslint --dev