webpack4.x学习笔记
栏目: JavaScript · 发布时间: 6年前
内容简介:webpack是一个模块打包工具,将每个资源文件看做是一个个模块,webpack依据打包规则将所有资源处理后打包到指定文件打包方案,告诉webpack如何处理特定的文件一段能扩展webpack功能的代码,可以在webpack运行到某个时刻的时候,帮助webpack做一些事情
webpack是一个模块打包工具,将每个资源文件看做是一个个模块,webpack依据打包规则将所有资源处理后打包到指定文件
支持的模块引入规范
- CommonJS
// 导入 import 模块名 from 模块路径; // 导出 export default 模块名; export const 模块名 = 模块内容; 复制代码
- CMD
// 导入 var 模块名 = required(模块路径); // 导出 module.exports = 模块名; 复制代码
- AMD
Mac webpack环境搭建
- 安装nodejs,webpack依赖node.js
- 进入node官网,点击带有 LTS 字眼按钮,下载稳定版node
- 点击压缩的安装包,一直点击下一步即可,
- 最后执行 node -v , npm -v 查看版本号,如果有说明安装成功,否则卸载,重新执行上诉步骤
- 执行 npm init ,初始化项目,一直按回车键,在新建的文件夹会生成一个package.json文件
{
"name": "webpack-demo",
"version": "1.0.0",
"private": true, // 是一个私有项目,不会上传到npm线上
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
复制代码
- 安装webpack(我的是4.34.0)
- 全局安装(不推荐)
npm install webpack webpack-cli -g webpack -v 查看全局webpack版本号
- 局部安装(推荐)
npm install webpack webpack-cli npx webpack -v 查看版本号 npx查找的是当前目录下的webpack
- 卸载
-
npm uninstall webpack webpack-cli
-
- 查看webpack版本记录
-
npm info webpack
-
- 全局安装(不推荐)
webpack配置文件(webpack.config.js)
const path = require('path'); // 导入node的path模块
module.exports = {
entry: './src/index.js', // 打包入口文件
output: {
filename: 'bundle.js', // 打包出的文件名
path: path.resolve(__dirname, 'dist') // 存放打包出的文件路径(绝对路径)
}
};
复制代码
webpack打包命令
// global webpack 文件名 // local npx webpack 文件名 复制代码
配置npm script(简化打包命令书写)
// package.json文件
"scripts": {
"bundle": "webpack"
// 执行npm run bundle命令,
// webpack会执行package.json文件下script字段里bundle对应的映射命令
}
复制代码
webpack-cli作用
- 能够在终端使用webpack命令
webpack打包日志
Hash: 178b79cd0f5fd66a90e5
Version: webpack 4.34.0 -- webpack版本
Time: 380ms -- 打包耗时
Built at: 06/18/2019 7:59:32 PM
// 文件名 大小 每一个打包的js文件id 每一个打包的js文件名
Asset Size Chunks Chunk Names
bundle.js 1.17 KiB 0 [emitted] main
Entrypoint main = bundle.js // 入口文件名(mian)
[0] ./src/index.js 203 bytes {0} [built] // 文件索引 文件路径 文件体积
[1] ./src/Footer.js 79 bytes {0} [built]
[2] ./src/Header.js 79 bytes {0} [built]
[3] ./src/Slider.js 79 bytes {0} [built]
复制代码
mode项
- 设置webpack的打包环境
- development:开发环境,专注于打包速度,不会压缩和tree sharking代码
- production:生成环境,专注于打包后的文件体积,会进行文件压缩和tree sharking去除无用代码,减小文件体积
Loader是什么
打包方案,告诉webpack如何处理特定的文件
module项配置loader
// package.json
module: { // 打包的模块
// 打包规则
rules: [{
test: /\.jpg$/, // 正则匹配使用loader解析的模块后缀名
use: {
loader: 'file-loader' // 用于解析该模块的loader
}
}]
}
复制代码
webpack打包流程
- 允许npm run bundle(实际上是执行webpack打包命令)
- webpack查看webpack配置文件,根据配置进行打包
- 如果遇到js文件,webpack自己处理解析;如果遇到其他文件,webpack会将该文件交给module项里能处理该类文件的loader处理,处理完后,将文件地址返回给引用该文件的变量
使用Loader打包静态资源(图片篇)
- file-loader
- 作用:将js中引用的文件资源抽离成单独的文件
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'file-loader',
options: {
// 占位符 placeholder
name: '[name]_[hash].[ext]',
outputPath: 'images/' // 处理后的文件存放位置: dist/images/xxx.png
}
}
}
复制代码
- url-loader
- 作用:将js中引用的文件资源转换为base64格式
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images/', // 处理后的文件存放位置: dist/images/xxx.png,
// size > 2.048kb 效果与file-loader一致
// size < 2.048kb 转换为base64字符串放入bundle.js中
limit: 2048
}
}
}
复制代码
使用Loader打包静态资源(样式篇)
- less-loader
- 作用:将less文件转换为css文件
{
test: /\.(c|le)ss/,
use: ['less-loader']
}
复制代码
- postcss-loader
- 作用:生成css AST树,方便postcss周边插件处理css代码
// webpack配置
{ // 样式处理
test: /\.(c|le)ss/,
use: ['postcss-loader', 'less-loader']
}
复制代码
// postcss.config.js配置
module.exports = {
plugins: [
require('autoprefixer'), // 自动添加属性前缀(后编译器)
]
};
复制代码
- css-loader
- 作用:分析多个css文件间的引用关系,将多个css文件合并成一段css
{
test: /\.(c|le)ss/,
use: ['css-loader', 'postcss-loader', 'less-loader']
}
复制代码
- style-loader
- 作用:将css-loader处理过后的内容,生成style标签插入到head标签里
{ // loader执行顺序为从上到下,从右到左
test: /\.(c|le)ss/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
}
复制代码
使用Loader打包静态资源(字体篇)
{ // 字体处理
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'assets/font/',
}
}
]
}
复制代码
什么是Plugins?
一段能扩展webpack功能的代码,可以在webpack运行到某个时刻的时候,帮助webpack做一些事情
- html-webpack-plugin
- 作用:根据html模板文件,生成一个新的html,并将打包生成的js引入html文件中
// 导入
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({ // 根据模板html, 生成新html文件
template: 'src/index.html', // html模板
})
]
复制代码
- clean-webpack-plugin
- 作用:删除文件指定文件夹
// 导入(新版本写法)
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins: [
new CleanWebpackPlugin(), // 删除当前目录dist文件夹
]
复制代码
SourceMap配置
打包代码与源码之间的一种映射关系,能够让开发人员快速的定位错误发生的位置
- source-map:会生成一个.map文件
module.exports = {
devtool: 'source-map',
};
复制代码
- inline-source-map:将map映射以base64格式写入main.js
module.exports = {
devtool: 'inline-source-map',
};
复制代码
- cheap-source-map:只显示出错的行数
module.exports = {
devtool: 'cheap-source-map',
};
复制代码
- eval:使用eval形式执行代码
module.exports = {
devtool: 'eval',
};
复制代码
// development:cheap-module-eval-source-map(推荐) // production:cheap-module-source-map(推荐) 复制代码
WebpackDevServer配置
- 安装webpack-dev-server
npm install webpack-dev-server --save-dev 复制代码
- 配置执行命令
"scripts": {
"start": "webpack-dev-server"
}
复制代码
- 配置webpack
devServer: { // 设置开发服务
contentBase: './dist', // 根目录
open: true, // 自动打开浏览器
port: 8080, // 端口号
proxy: { // 设置接口代理(解决跨域)
'/api': 'https://localhost:3000'
}
}
复制代码
node环境使用WebpackDevServer功能
- 安装express(node的框架)
npm install express --save-dev 复制代码
- 安装webpack-middleware(监听src目录下文件变化)
npm install webpack-middleware --save-dev 复制代码
- 编写server.js
const express = require('express');
const webpack = require('webpack');
const WebpackMiddleWare = require('webpack-middleware');
const config = require('./webpack.config');
// 生成express实例(服务器)
const app = express();
// 创建webpack编译器(能够进行webpack打包)
const complier = webpack(config);
// 使用webpack-middleware插件监听webpack打包的文件变化
app.use(WebpackMiddleWare(complier, {}));
// 开启监听
app.listen(3000, () => {
console.log('server is running at 3000');
});
复制代码
- 配置server执行命令
"scripts": {
"server": "node server.js"
}
复制代码
热模块替换(Hot Module Replacement)
实现局部更新,而非浏览器页面刷新
devServer: {
hot: true, // 开启HMR
hotOnly: true, // 不更新浏览器
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
// entery文件末尾添加
if (module.hot) {
module.hot.accept();
}
复制代码
配置Babel编译ES6语法
babel:只能解析ES的语法,而不能解析对象的API,Promise等; @babel/polyfill:解析babel不能解析的部分
- 安装babel-loader、@babel/preset-env、@babel/core、@babel/polyfill
npm install babel-loader @babel/preset-env @babel/core @babel/polyfill 复制代码
- 配置
module: {
rules: [
{ // babel处理
test: /.js$/,
exclude: /node_modules/, // 排除文件
loader: 'babel-loader'
}
]
}
复制代码
// .babelrc文件
{
"presets": [
[
"@babel/preset-env", // 将ES5以上的语法转换为ES5版本
{
"useBuiltIns": "usage" // 按需使用polyfill
}
]
]
}
复制代码
// index.js import '@babel/polyfill'; 复制代码
使用babel-polyfill可能会造成全局变量名污染,如果有使用babel打包第三方包,则使用transform-runtime方案
配置React代码打包环境
- 安装react、react-dom
npm install react react-dom --save 复制代码
- 安装@babel/preset-react
npm install @babel/preset-react --save-dev 复制代码
- .babelrc配置
{
"presets": [
["@babel/preset-react"]
]
}
复制代码
Tree Sharking
删除模块中未使用的内容,减小打包体积(只支持ES Module的引入方式)
开发环境
- 配置webpack.config
module.exports = {
mode: 'development'
optimization: {
usedExports: true, // 打包被引用的模块
}
};
复制代码
- 配置package.json
{
"sideEffects": false // 所有模块都进行tree sharking
}
复制代码
生成环境
- 配置webpack.config
module.exports = {
mode: 'production'
};
复制代码
- 配置package.json
{
"sideEffects": false // 所有模块都进行tree sharking
}
复制代码
Development和Production模式
- development(开发模式)
- 关注打包速度,不会进行代码压缩
- production(生产模式)
- 关注打包文件体积,会对代码进行压缩,tree sharking等操作
根据模式拆分webpack.config文件
- 安装webpack-merge用以合并webpack配置文件
npm install webpack-merge --save-dev 复制代码
- webpack.common.js:公共配置
const path = require('path'); // 导入node的path模块
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
main: './src/index.js', // 打包入口文件
},
output: {
filename: 'script/[name].js', // 打包出的文件名
path: path.join(__dirname, '../', 'dist'), // 存放打包出的文件路径(绝对路径)
// publicPath: './', // 公共路径
},
module: { // 打包模块
// 打包规则
rules: [
{ // babel处理
test: /.js$/,
exclude: /node_modules/, // 排除文件
loader: 'babel-loader'
},
{ // 图片处理
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images/', // 处理后的文件存放位置: dist/images/xxx.png
limit: 10240, // 当处理的文件大小大于2048kb,效果与file-loader一致;小于时,转换为base64字符串放入bundle.js中
}
}
}, { // 字体处理
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'font/',
}
}
]
}, { // csv文件处理
test: /\.(csv|tsv)$/,
use: ['csv-loader']
}, { // xml文件处理
test: /\.xml$/,
use: ['xml-loader']
}, { // 样式处理
test: /\.less/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2, // 让less文件里引入的其他文件也经过后面两个loader处理
// modules: true, // css模块化(css文件只在当前模块有效)
}
},
'postcss-loader',
'less-loader'
]
}, {
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({ // 根据模板html, 生成新html文件
template: 'src/index.html'
}),
new CleanWebpackPlugin({ // 清除文件夹
dry: false
})
]
};
复制代码
- webpack.prod.js:生产环境配置
const webpackMerge = require('webpack-merge'); // 合并webpack配置文件
const commonConfig = require('./webpack.comm');
const prodConfig = {
mode: 'production', // 打包环境
// development:cheap-module-eval-source-map(推荐)
// production:cheap-module-source-map(推荐)
devtool: 'none', // 设置源文件与打包文件的映射关系
};
module.exports = webpackMerge(commonConfig, prodConfig);
复制代码
- webpack.dev.js:开发模式配置
const webpack = require('webpack');
const webpackMerge = require('webpack-merge'); // 合并webpack配置文件
const commonConfig = require('./webpack.comm');
const devConfig = {
mode: 'development', // 打包环境
// development:cheap-module-eval-source-map(推荐)
// production:cheap-module-source-map(推荐)
devtool: 'cheap-module-eval-source-map', // 设置源文件与打包文件的映射关系
devServer: { // 设置开发服务
contentBase: './dist', // 根目录
open: true, // 自动打开浏览器
port: 8080, // 端口号
hot: true, // 开启HMR
hotOnly: true, // 不更新浏览器
proxy: { // 设置接口代理(解决跨域)
'/api': 'https://localhost:3000'
}
},
optimization: {
usedExports: true, // 打包被引用的模块
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
module.exports = webpackMerge(commonConfig, devConfig);
复制代码
- package.json修改
"scripts": {
"start": "webpack-dev-server --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js",
"server": "node server.js"
},
复制代码
Code Splitting进行代码分割
将重复代码抽离出来形成单独的chunk,避免单个文件过大,而造成文件请求时间过长
同步代码实现代码分割,配置optimization项
optimization: {
splitChunks: { // 代码分割
chunks: 'all', // 自动检测应该分离的代码
}
}
复制代码
异步代码实现代码分割(import导入的模块)
webpack会自动将异步代码打包到单独的文件中,但webpack在打包时,无法识别动态异步引入语法,所以我们需要安装@babel/plugin-syntax-dynamic-import来支持动态异步引入语法
- 安装@babel/plugin-syntax-dynamic-import
# 支持动态异步引入模块 npm install --save-dev @babel/plugin-syntax-dynamic-import --save-dev 复制代码
- 配置.babelrc文件
{
"plugins": [
"@babel/plugin-syntax-dynamic-import"
]
}
复制代码
SplitChunksPugin配置参数
- webpack默认配置项
splitChunks: {
chunks: "async",
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
复制代码
- 注释版
splitChunks: {
chunks: 'all', // 代码分割目标:async(异步代码) all(异步和同步代码) initial(同步代码)
minSize: 30000, // 模块size > minSize(30KB)进行代码分割
// maxSize: 50000, // 分割出的模块size > maxSize(50KB)进行二次分割
minChunks: 1, // 模块使用次数 > minChunks进行代码分割
maxAsyncRequests: 5, // 异步模块内部最大并行请求数
maxInitialRequests: 3, // 入口并行加载的最大请求数(入口文件最多能拆分3个文件被http请求)
automaticNameDelimiter: '~', // 文件名连接符
name: true, // 自动生成文件名
cacheGroups: { // 分割代码缓存组(同步代码分割有效)
vendors: { // vendors组,入口文件:main.js
test: /[\\/]node_modules[\\/]/, // 分割nodule_modules下的代码
priority: -10, // 分割优先级(当模块符合多个组时,放在优先级高的组中)
filename: 'vendors.js' // 打包文件名
},
default: { // default组,入口文件:main.js
priority: -20,
reuseExistingChunk: true, // 忽略已打包过的模块
filename: 'common.js'
}
}
}
复制代码
打包分析
- 安装 webpack-bundle-analyzer插件
npm install --save-dev webpack-bundle-analyzer 复制代码
- webpack中使用
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
};
复制代码
Preloading
与核心js文件一起下载(不推荐)
Prefetching(加快首屏渲染)
等待核心js文件下载完毕,网络带宽空闲了,再去下载其他模块资源(推荐)
提取css
- 安装mini-css-extract-plugin
# 将css从js文件中抽离出来 npm install --save-dev mini-css-extract-plugin 复制代码
- 配置webpack.prod.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [{ // 样式处理
test: /\.(le|c)ss/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../', // 提取出来的css文件里都会添加公共路径
hmr: process.env.NODE_ENV === 'development'
}
}, {
loader: 'css-loader',
options: {
importLoaders: 2, // 让less文件里引入的其他文件也经过后面两个loader处理
// modules: true, // css模块化(css文件只在当前模块有效)
}
},
'postcss-loader',
'less-loader'
]
}]
},
plugins: [
new MiniCssExtractPlugin({ // 抽离js文件里的css
filename: 'static/css/[name].[hash].css', // html直接引入的css文件
chunkFilename: 'static/css/[id].[hash].css' // 间接引入的css文件
})
],
};
复制代码
- 安装optimize-css-assets-webpack-plugin
# 进行css压缩 npm install --save-dev optimize-css-assets-webpack-plugin 复制代码
- 配置webpack.prod.js
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({ // css代码压缩
})
]
}
};
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 【每日笔记】【Go学习笔记】2019-01-04 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-02 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-07 Codis笔记
- Golang学习笔记-调度器学习
- Vue学习笔记(二)------axios学习
- 算法/NLP/深度学习/机器学习面试笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深度学习
[美] 伊恩·古德费洛、[加] 约书亚·本吉奥、[加] 亚伦·库维尔 / 赵申剑、黎彧君、符天凡、李凯 / 人民邮电出版社 / 2017-7-1 / 168
《深度学习》由全球知名的三位专家Ian Goodfellow、Yoshua Bengio 和Aaron Courville撰写,是深度学习领域奠基性的经典教材。全书的内容包括3个部分:第1部分介绍基本的数学工具和机器学习的概念,它们是深度学习的预备知识;第2部分系统深入地讲解现今已成熟的深度学习方法和技术;第3部分讨论某些具有前瞻性的方向和想法,它们被公认为是深度学习未来的研究重点。 《深度......一起来看看 《深度学习》 这本书的介绍吧!