webpack4.x学习笔记
栏目: JavaScript · 发布时间: 5年前
内容简介: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/深度学习/机器学习面试笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
你的品牌,价值千万
温迪 / 人民邮电出版社 / 2018-7-1 / 49.00元
“大道无术,万法归心。” 不管是互联网、社交媒体,还是 AI 怎样让人眼花缭乱。从“真心”出发塑造的个人品牌,都将带你从容面对任何一种变化的冲击。现代生活变得越来越透明,如果你不懂得如何真实、精准地定位和呈现自己,你的个人品牌在 碎片信息中被误解、被曲解就是一种必然。 本书分四步引导你剖析自己、发现自我,构建可持续的品牌生态系统,策划品牌战略,提升个人呈现力,并在最后带你勾画出一幅完整的个人......一起来看看 《你的品牌,价值千万》 这本书的介绍吧!
URL 编码/解码
URL 编码/解码
RGB HSV 转换
RGB HSV 互转工具