项目安装,通常是每个项目不同的webpack版本,所以局部安装
cdn配置
vue3.2 $ref,不用加.value
plugins: [
/* 是否开启 $ref , vue3.2 的语法糖 */
vue({
refTransform: true, // 主要是这句,不能用const XXX = $ref,必须用let
reactivityTransform: true
}),
],
1 $ npm install webpack --save-dev
或者$ npm install webpack -D
npm i webpack-cli@3.3.12 -D
npx webpack-cli init ,然后出现下面提示:
ℹ INFO For more information and a detailed description of each question, have a look at https://github.com/webpack/webpack-cli/blob/master/INIT.md
ℹ INFO Alternatively, run `webpack(-cli) --help` for usage info.
? Will your application have multiple bundles? No
? Which module will be the first to enter the application? [default: ./src/index]
? Which folder will your generated bundles be in? [default: dist]:
? Will you be using ES2015? Yes
? Will you use one of the below CSS solutions? No
+ babel-plugin-syntax-dynamic-import@6.18.0
+ uglifyjs-webpack-plugin@2.0.1
+ webpack-cli@3.2.3
+ @babel/core@7.2.2
+ babel-loader@8.0.4
+ @babel/preset-env@7.1.0
+ webpack@4.29.3
added 124 packages from 39 contributors, updated 4 packages and audited 25221 packages in 7.463s
found 0 vulnerabilities
Congratulations! Your new webpack configuration file has been created!
如果用webpack-cli init,可以跳到下面3.2
2 npm init -y 初始化生成package.json
3 配置webpack.config.js
https://www.npmjs.com/package/file-loader //官方包管理帮助
3.1 loader:
npm i -D style-loader css-loader // css打包成一个,名字不重复加hash
npm i -D postcss-loader //浏览器前缀兼容性
npm install --save-dev less-loader //less 必须放在css对象的最后面,因为先编译
npm install autoprefixer -D // 浏览器前缀兼容性
npm i -D optimize-css-assets-webpack-plugin // css压缩
npm i -D url-loader // 小于多少k的小图,打包成base64位
npm i -D file-loader // 把文件打包,命名管理,字体转为module模块加载
babel-loader // es6=>es5
3.2 plugins
npm i -D html-webpack-plugin // html打包
npm i -D clean-webpack-plugin // 清除dist文件夹
npm i -D mini-css-extract-plugin // css和js分离打包,
loader中:MiniCssExtractPlugin.loader,替换掉 loader中的 ‘style-loader’,
plugins中:new MiniCssExtractPlugin({filename: ‘css/[name].css’,}),
3.3优化webpack效率的plugins
HRM 热跟新模块
npm i -D thread-loader // 多进程打包
npm i -D terser-webpack-plugin // 多进程压缩
npm i - D polyfill
npm i -D webpack-dev-server // web服务器
package.json中加 “start”: “webpack-dev-server”
webpack.config.js中加
devServer: {
contentBase: ‘./dist’, // 服务器根目录
open: true, // 自动打开服务
compress: true,
port: 8000
},
npm run start // 开发模式
npm run build // 生产模式
1.entry入口文件
2.output打包文件路径配置
3.mode:production或者development
4.devServe配置 端口,代理,压缩
4.module里面loader配置
5.plugins插件配置
6.devtool:有7种模式,最佳是cheap-module-eval-source-map
webpack原理:
参考地址
entry里面的 chunk
根据中间的配置Loader plugins devServer devtool
output打包输出 boundle
1.从chunk中找到入口模块路径
2.先检查模块缓存池中是否已经有加载过该入口模块, 如果已经加载过该模块则结束构建直接使用缓存池中的该模块
3.如果没有加载过该模块则读取文件内容
4.将整个文件内容丢入AST词法分析
AST词法分析就是你给他一串代码, 他给你一个对象, 对象里有对该代码的描述, 包括你调用了几个函数, 每个函数名叫啥都是用一个对象形式包裹
5.从AST词法分析结果中去找一些关键字( require, import等 ), 通过这些关键字找到该模块依赖的其他模块路径, 将他们的路径以绝对路径的方式保存进一个叫做dependencies的数组中
6.替换整个该模块中的require, import等关键字, 替换成__webpack_require
7.保存转换后的代码
8.将denpendencies中的依赖递归加载
源码地址](https://gitee.com/hkduan/webpack-configuration/tree/master/demo-js)
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
// 配置webpack的内置代码优化选项
mode: "production", // "production" | "development" | "none"
// base directory,配置资源入口entry是从哪个目录为起点的。绝对路径字符串。
// 默认为当前工程根目录, process.pwd()
context: path.resolve(__dirname, './src'),
// Webpack资源入口entry代表的路径,要是相对路径。
// string | object | array
// 字符串形式: 是最简单的形式,表示打包的入口JS文件。
// 数组形式:数组最后一个文件是资源的入口文件,数组其余文件会预先构建到入口文件。本质还是一个入口。
// entry: ['core-js/stable', 'regenerator-runtime/runtime', './a.js'],
// 对象形式:多入口配置,每个入口文件各自寻找自己依赖的文件模块打包成一个JS文件,最终得到多个js文件。
// entry: {
// app: ['core-js/stable', 'regenerator-runtime/runtime', './a.js'],
// vendor: './vendor'
// },
// 入口也可以自定义函数,返回值是以上三种形式即可,可以用来做一些额外逻辑。
// 对构建过程不进行额外的处理的情况下一个入口只会生成一个打包后的文件,这也是Webpack的构建本质。
entry: 'main.js'
// webpack 如何输出结果的相关选项
outout: {
// 所有输出文件的目标路径,必须是绝对路径,默认为dist目录。
// 需要注意的是,path输出路径表示的是在磁盘上构建生成的真实文件存放地址。我们在开发时,一般会用webpack-dev-server开启一个本地服务器,这个服务器可以自动刷新和热加载等,它生成的文件是在内存中而不是在电脑磁盘。该内存中的文件路径,我们会用Webpack配置文件的devServer配置项的publicPath表示,它虚拟映射了电脑磁盘路径。
path: path.resolve(__dirname, 'dist'),
// filename是打包后生成的资源名称
// filename除了可以是一个文件名称,也可以是相对地址,例如'./js/bundle.js'。最终打包输出的文件是path绝对路径与filename的拼接后的地址。
// filename支持类似变量的方式生成动态文件名,例如[hash]-bundle.js,其中方括号很像占位符,hash表示特定的动态值。
// 特定动态值除了[hash],还有[name]。
// [name]表示的是chunk的名称,chunk简单理解的话就是打包过程中,一个资源入口代表一个chunk,一个异步模块资源也代表一个chunk。
// 其中字符串和数组形式的entry,output.filename的[name]值都是main。
// 对于entry是对象形式的多入口配置,[name]是对象的属性名,对应每一个入口文件。
filename: '[name]-[hash:8].js', // [name].[chunkhash:8].js 多入口
// output中的publicPath表示的是资源访问路径, 即打包完成后告知浏览器访问资源的路径。
// 表示形式有两大类:相对路径与绝对路径。
// 以当前浏览的页面url是 https://www.apple.com/ipad/ ,要访问的资源名称是bundle-3fa2.js为例讲解。
// 1.相对路径
// 相对路径又可以分类两种情况,第一种,它相对于当前浏览的HTML页面路径取值的。
// (1) output.publicPath以"./"或"../"等开头,表示要访问的资源以当前页面url作为基础路径。
// publicPath: "" // 资源的访问地址是https://www.apple.com/ipad/bundle-3fa2.js
// publicPath: "../dist/" // 资源的访问地址是https://www.apple.com/dist/bundle-3fa2.js
// publicPath: "./dist/" // 资源的访问地址是https://www.apple.com/ipad/dist/bundle-3fa2.js
// (2) output.publicPath以"/"开头,表示要访问的资源以当前页面的服务器地址作为基础路径。
// publicPath: "/" // 资源的访问地址是https://www.apple.com/bundle-3fa2.js。
// publicPath: "/dist/" // 资源的访问地址是https://www.apple.com/dist/bundle-3fa2.js。
// 2.绝对路径
// output.publicPath的值以HTTP协议名称开始。一般在使用CDN的时候,因为CDN的域名与我们自己服务器的域名不一样,我们会采用这种方式。
// Web中常见的协议名称有http和https,例如我的网站 https://www.jiangruitao.com/ 的协议名称就是https。
// 还有一种叫做相对协议的形式,它以 // 开头,也就是省略了前面的https:或http:。
// 在使用相对协议的时候,浏览器会对前页面使用的协议名称与相对协议拼接。
// 下面看一下output.publicPath的值以协议开始的例子,在以协议开始的publicPath时,资源的访问地址是publicPath代表的绝对路径加上资源名称。
// publicPath: "https://cdn.apple.net/" // 资源的访问地址是https://cdn.apple.net/bundle-3fa2.js
// publicPath: "http://cdn.apple.net/" // 资源的访问地址是http://cdn.apple.net/bundle-3fa2.js
// publicPath: "//cdn.apple.net/dist/" // 资源的访问地址是https://cdn.apple.net/dist/bundle-3fa2.js
publicPath: '/',
// 打包过程中非入口文件的chunk名称,通常在使用异步模块的时候,会生成非入口文件的chunk。
chunkFilename: '[id].js'
},
// webpack中一切皆模块,webpack本身可以处理JS和Json文件,对于其他文件模块,可以使用loader来进行解析。
// 常用loader:css-loader, style-loader, url-loader, babel-loader, vue-loader
module: {
rules: [
{
// 正则表达式或正则表达式数组
test: /\.js$/,
include: /src/,
// include: [
// path.resolve(__dirname, "app")
// ],
exclude: /node_modules/,
// exclude: [
// path.resolve(__dirname, "app/demo-files")
// ],
// 字符串,对象或数组,多个loader从后向前执行
use: ['babel-loader']
},
{
test: /\.js$/,
use: ['eslint-loader'],
// 对相同后缀名的模块,强制某个loader最先处理或最后处理,可以使用enforce项。
// 'pre'和'post'
// Pre表示这个loader在所有的loader之前执行,post表示这个loader在所有的loader执行后再执行。
enforce: 'pre',
exclude: /node_modules/,
},
// 在Webpack中被加载的模块我们称之为resource,而实施加载的模块我们称之为issuer。
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
exclude: /node_modules/,
// 指定只有src目录下的JS引用的CSS可以被相应的loader处理,那么可以配置issuer
issuer: {
test: /\.js$/,
include: /src/
}
}
]
},
// 插件,webpack就是建立在插件系统之上
// 常用插件:HtmlWebpackPlugin,CleanWebpackPlugin,CopyPlugin等等
plugins: [
new HtmlWebpackPlugin(),
new CleanWebpackPlugin(),
new CopyPlugin({
patterns: [
{ from: path.resolve(__dirname, 'src/static/'), to: path.resolve(__dirname, 'dist/static/') },
],
})
]
}