npm install vue-cli -g
vue create vue2_weback_demo
vue create 和vue init 两种创建方式的区别
使用方式:vue create 项目名称
webpack是官方推荐的标准模板名 使用方式:vue init webpack 项目名称
使用方式:vue init simulatedgreg/electron-vue 项目名称
npm install
npm run serve
npm run build
npm run lint
npm install webpack webpack-cli -D
npm install webpack-dev-server -D
webpack.config.js 初始化配置是参考B栈视频学习整理的,有兴趣的小伙伴也可以看一下,话不多说,下面进入配置 参考视频
module.exports = {
// 也可以配置为一个数组,配置多入口
entry: './src/main.js',
mode: "development",
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
}
// 用来处理获取的样式
function getStyleLoaders(pre) {
return [MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
// plugins: [["autoprefixer"]],
plugins: ['postcss-preset-env'],//能解决大多数兼容性问题
},
},
}, pre].filter(Boolean);
}
module: {
rules: [
{ test: /\.css$/,// 匹配的条件
use: [
// 通过style标签动态插入style标签
'style-loader',
// 把css代码转化为js代码,css-loader是处理css文件的loader
'css-loader'
] },
{
test: /\.less$/,
use: getStyleLoaders("less-loader"), // 从右向左解析原则
// use: ["style-loader", "css-loader", "less-loader"]
},
{
test: /\.s[ac]ss$/,
use: getStyleLoaders("sass-loader")
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
// cacheDirectory: true, // 开启babel缓存
// cacheCompression: false,// 关闭缓存文件压缩
// plugins: ['@babel/plugin-transform-runtime'],
},
},]
},
{
test: /\.(gif|png|jpe?g)$/i,
type: "asset",
parser: {
dataUrlCondition: {
// 小于10kb的图片转成base64,减少请求数量
// 缺点:体积会大一点
maxSize: 10 * 1024, // 小于10kb
},
},
generator: {
// 输出图片的名称
filename: "imgs/[name].[contenthash:8][ext]",
},
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, //媒体文件
// 对文件原封不动的输出
type: "asset/resource",
// generator: {
// filename: "media/[name].[contenthash:8][ext]",
// },
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, // 字体
type: "asset/resource",
// generator: {
// filename: "fonts/[name].[contenthash:8][ext]"
// }
},
]
},
我们打包前,要先保证代码正确,这个时候就用到了eslint 配置文件由很多种写法: .eslintrc.*:新建文件,位于项目根目录 .eslintrc .eslintrc.js .eslintrc.json 区别在于配置格式不一样 package.json 中eslintconfig:不需要创建文件,在原有文件基础上写ESLint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
npm install eslint-webpack-plugin eslint --save-dev
我的代码里面配置@vue/cli-plugin-eslint 所以不用安装上面这个步骤 -- 参考链接webpack官网 plugin配置 webpack官网
npm install eslint-webpack-plugin --D
const ESLintPlugin = require('eslint-webpack-plugin');
3、在plugins中配置
plugins:[
...
new ESLintPlugin({
// 配置哪些目录需要检查
context: path.resolve(__dirname, './src'),
}),
]
// 继承eslint规则
extends:["eslint:recommended"]
env :{
"node":true,//启用node中全局变量
"browser":true,//启用浏览器中全局变量
}
parserOptions:{
"ecmaVersion":6, //使用es6语法
"sourceType": "module" //使用模块化语法
}
rules:{
"no-var":2,//不能使用 var 定义变量
}
dist
配置好eslint之后,就是要配置babel,他能将高级的js语法转换成低版本的js语法,处理各种兼容问题。
npm i babel-loader @babel/core @babel/preset-env -D
我安装babel已包含上述插件,无需再安装
babel官网配置 2. 在webpack中配置babel
module:{
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
}
module.exports = {
// 智能预设能编译最新的es6
presets: ['@babel/preset-env'],
};
对于js来说何时用babel-loader何时用esbuild-loader
- 主要功能:通过 Babel 转译 JavaScript 代码,支持 ES6+ 语法转换为兼容性更高的代码。 灵活性:支持多种插件和预设(如 @babel/preset-env、@babel/plugin-transform-runtime 等),可以满足复杂的转译需求。
- 生态丰富:Babel 的插件生态系统非常强大,能够处理各种语言特性(如 TypeScript、Flow 等)。
- 速度较慢:由于 Babel 是基于 JavaScript 实现的,转译速度相对较慢,尤其是在大规模项目中。 使用场景
- 当需要对现代 JavaScript 语法进行深度转译时(如支持 IE 浏览器)。
- 当需要使用 Babel 插件来实现特定功能时(如 polyfill、代码优化等)。 esbuild-loader 特点
- 主要功能:通过 esbuild 工具快速转译 JavaScript 代码,专注于性能优化。
- 速度快:esbuild 是用 Go 语言编写的,转译速度远快于 Babel。
- 简单易用:默认支持 ES6+ 语法转译,无需额外配置插件或预设。
- 功能有限:相比 Babel,esbuild 的功能较为单一,不支持复杂的插件系统。 使用场景
- 当项目对转译速度有较高要求时(如开发环境中的热更新)。
- 当只需要简单的 ES6+ 语法转译,而不需要复杂的功能(如 polyfill 或特定插件)
我当前项目是vue2+webpack 所以用的是esbuild-loader
html-webpack-plugin 是一个用于在 webpack 的构建过程中生成 HTML 文件的插件。它允许您使用一个简单的模板文件,并自动将生成的 bundle 文件插入到模板文件中,从而生成一个完整的 HTML 文件。 使用方式如下:
new HtmlWebpackPlugin({
// 模版:以public/index.html为模板生成打包后的index.html
template: path.resolve(__dirname, "./public/index.html"),
BASE_URL: process.env.BASE_URL || '/'
}),
npm install wwebpack-dev-server --D
在webpack.config.js中配置devServer
devServer: {
static: {
directory: path.resolve(__dirname, "./dist"), // 打包后的文件路径 directory:目录
},
open: true, //自动打开浏览器
compress: true, //启动gzip压缩
port: 9000, // 端口号
},
本插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
将style-loder 替换为 MiniCssExtractPlugin.loader
{
test: /\.css$/,
// MiniCssExtractPlugin.loader 最终会将css提取到单独的文件
use: [MiniCssExtractPlugin.loader, "css-loader"], // 从右向左解析原则
// use: ["style-loader", "css-loader"]
}
然后在插件中调用一下
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash:8].css"
}),
npm i postcss-loader postcss postcss-preset-env -D
{
test: /\.s[ac]ss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
plugins:['postcss-preset-env'],//能解决大多数兼容性问题
postcssOptions: {
plugins: [["autoprefixer"]],
},
},
},
"sass-loader",
], // scss的loader
},
"browserslist": [
"> 1%", // 全球超过1%的浏览器
"last 2 versions", // 最近两个版本
"not dead" // 排除已经不再维护的浏览器
]
CssMinimizerWebpackPlugin 是一个用于优化和压缩 CSS 的 webpack 插件。它使用 cssnano 来优化和压缩 CSS,并支持 source maps 和 assets 中使用查询字符串。
npm install css-minimizer-webpack-plugin --save-dev
webpack官方给出的代码
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /.s?css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
// `...`,
new CssMinimizerPlugin(),
],
},
plugins: [new MiniCssExtractPlugin()],
};
我直接在plugins中配置了CssMinimizerPlugin
ERROR in Template execution failed: ReferenceError: BASE URL is not defined
ERROR in ReferenceError: BASE URL is not defined
plugins: [
...
new DefinePlugin({
// window.ENV = 'production'
ENV: JSON.stringify('production'),
BASE_URL: '"../"' // 定义全局变量BASE_URL
}),
],
[项目地址] (https://gitee.com/pear66/vue-webpack5)
我们从 4 个角度对 webpack 和代码进行了优化:
此选项控制是否生成,以及如何生成 source map。使用 SourceMapDevToolPlugin 进行更细粒度的配置。查看 source-map-loader 来处理已有的 source map。 SourceMap(源代码映射)是一个用来生成源代码与构建后代码--映射的文件的方案。它会生成一个 xx.map 文件,里面包含源代码和构建后代码每一行、每一列的映射关系。当构建后代码出错了,会通过 xxx.map 文件,从构建后代码出错位置找到映射后源代码出错位置,从而让浏览器提示源代码文件出错位置,帮助我们更快的找到错误根源。 开发模式用
devtool: 'cheap-module-source-map',
devtool: 'source-map',
HMR (HotModuleReplacement),即热模块替换,是 webpack 的一个功能,它可以在运行时更新模块,而无需完全刷新整个页面。
devServer: {
...
hot:true, // 提供HMR功能,只更新某个模块,没有替换整个项目
},
在模块中判断
if(module.hot){
module.hot.accept('./xxx')
}
实际开发并不需要上述这样,直接配置loader,以vule为例 vue-loader,生产模式不需要
module: {
rules: [
// oneOf 不支持 vue-loader ,要单独拿出来
{
test: /\.vue$/,
loader: "vue-loader",
},
// 每个文件只有一个loader配置处理
{
oneOf: [
{
test: /\.(gif|png|jpe?g)$/i,
type: "asset",
parser: {
dataUrlCondition: {
// 小于10kb的图片转成base64,减少请求数量
// 缺点:体积会大一点
maxSize: 10 * 1024, // 小于10kb
},
},
generator: {
// 输出图片的名称
filename: "imgs/[name].[contenthash:8][ext]",
},
},
]
}
],
},
module: {
rules: [
{
test: /\.(js|ts|jsx|tsx)$/,
include: path.resolve(__dirname, 'src'),
// exclude: /node_modules/,
// loader:"babel-loader",
loader: 'esbuild-loader',
generator: {
target: 'es2015'
}
},
]
}
include和exclude的只写一个即可
plugins: [
new ESLintPlugin({
// 配置哪些目录需要检查
context: path.resolve(__dirname, './src'),
exclude: 'node_modules',// 不写 默认也有
}),
]
对eslint检查和babel编译进行缓存,提升打包速度
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
cacheDirectory: true, // 开启babel缓存
cacheCompression: false,// 关闭缓存文件压缩
},
},
},
eslint 开启缓存
new ESLintPlugin({
// 配置哪些目录需要检查
context: path.resolve(__dirname, './src'),
exclude: 'node_modules',// 不写 默认也有
cache: true,// 开启缓存
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'),
}),
const os = require('os');
const threads = os.cpus().length;
npm install thread-loader --D
在loader配置多进程
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'thread-loader',
options: {
workers: threads, // 开启几个子进程去完成
}
},
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
cacheDirectory: true, // 开启babel缓存
cacheCompression: false,// 关闭缓存文件压缩
},
},]
},
在eslint中开启多进程
new ESLintPlugin({
// 配置哪些目录需要检查
context: path.resolve(__dirname, './src'),
cache: true,// 开启缓存
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'),
threads,
}),
引入压缩的插件
const TerserWebpackPlugin = require("terser-webpack-plugin");
在plugins中配置
new TerserWebpackPlugin({
parallel: threads, // 开启多进程
extractComments: false, // 移除注释
terserOptions: {
compress: {
pure_funcs: ['console.log'], // 移除console.log
},
},
}),
在optimization添加压缩配置
// 用于处理压缩
optimization: {
...
minimizer: [
// CssMinimizerPlugin、TerserWebpackPlugin 也可以放在plugins中
new CssMinimizerPlugin(),
new TerserWebpackPlugin({
parallel: threads, // 开启多进程
extractComments: false, // 移除注释
terserOptions: {
compress: {
pure_funcs: ['console.log'], // 移除console.log
},
},
}),
],
},
减少babel体积
npm i @babel/plugin-transform-runtime --D
在babel中配置
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'thread-loader',
options: {
workers: threads, // 开启几个子进程去完成
}
},
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
cacheDirectory: true, // 开启babel缓存
cacheCompression: false,// 关闭缓存文件压缩
plugins: ['@babel/plugin-transform-runtime'],
},
},]
},
下载包
npm i image-minimizer-webpack-plugin --D
无损压缩(包下载不下来)
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --D
有损压缩
npm install imagemin-gifsicle imagemin-jpegtran imagemin-pngquant imagemin-svgo --D
包不好下
optimization: {
...
minimizer: [
...
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: [
['gifsicle', { interlaced: true }],
['jpegtran', { progressive: true }],
['optipng', { optimizationLevel: 5 }],
[
'svgo',
{
plugins: [
'preset-default',
"prefixIds",
{
name: "sortAttrs",
params: {
xmlnsOrder: "alphabetical"
}
}
]
},
],
]
}
}
})
],
},
const HtmlWebpackPlugin=require("html-webpack-plugin");
module.exports ={
// entry:'./src/main.js',// 只有一个入口文件,单入口
entry:{ // 有多个入口文件,多入口
app:"./src/app.js"
main:"./src/main.js"
}
output:{
path: path.resolve( dirname,"dist"),
filename: "[name].js",// webpack命名方式,[name]以文件名自己命名filename
}
plugins:[
new HtmlWebpackPlugin({template:path.resolve( dirname,"public/index.html")})
],
mode:"production"
}
optimization: {
minimize: true, // 强制启用压缩
// 对代码进行分割
splitChunks: {
chunks: 'all',
// 以下是默认值
// minsize:20000,//分割代码最小的大小
// minRemainingsize:0,//类似于minsize,最后确保提取的文件大小不能为0// minChunks:1,//至少被引用的次数,满足条件才会代码分割
// maxAsyncRequests:3e,/按需加载时并行加载的文件的最大数量
// maxInitialRequests:30,//入口js文件最大并行请求数量
// enforcesizeThreshold:50000,
// 超过50kb一定会单独打包(此时会忽略minRemainingsize、maxAsyncRequests、maxInitialRegquests)
//cacheGroups:{// 组,哪些模块要打包到一个组)
// defaultVendors:{//组名
// test:/[\V/]node_modules[\\/]/,//需要打包到一起的模块
// priority:-10,//权重(越大越高)
// reuseExistingchunk:true,//如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,
// 而不是生成新的模块
// },
// default:{ // 其他没有写的配置会使用上面的默认值
// {
// minChunks:2,//这里的minChunks权重更大
// priority: -20,
// reuseExistingchunk: true,
// }
},
// runtimeChunk: 'single',
minimizer: [
new CssMinimizerPlugin(),
]
},
output: {
clean: true, // 清理 /dist 文件夹
// filename: "js/main.js", // 打包后的文件名称
filename: "js/[name].[contenthash:8].js", // 打包后的文件名称
// 打包输出的其他文件名称
chunkFilename: "js/[name].[contenthash:8].chunk.js",
path: path.resolve(__dirname, "../dist"), // 打包后的目录
// 图片 等字体通过type: asset处理资源命名方式
assetModuleFilename: 'media/[name].[contenthash:8][ext][query]',
},
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash:8].css"
}),
添加 移除loader中字体、媒体文件的命名规则
// generator: {
// filename: "fonts/[name].[contenthash:8][ext][query]"
// }
runtimeChunk:{
name:(entrypoint)=>runtime~${entrypoint.name}.js`
}
过去我们使用 babel 对js 代码进行了兼容性处理,其中使用@babe/preset-env 智能预设来处理兼容性问题它能将 ES6 的一些语法进行编译转换,比如箭头函数、点点点运算符等。但是如果是 async 函数、promise 对象、数组的一些方法(includes)等,它没办法处理 所以此时我们js 代码仍然存在兼容性问题,一旦遇到低版本浏览器会直接报错。所以我们想要将js 兼容性问题彻底解决 core-js 是专门用来做ES6 以及以上API的 polyfill。 polyfi11 翻译过来叫做垫片/补丁。就是用社区上提供的一段代码,让我们在不兼容某些新特性的浏览器上,使用该新特性。 例如:Promise 就没有被打包
return new Promise(resolve => {
resolve("成功");
});
解决方案:
module.exports = {
presets: [
'@babel/preset-env',
{
useBuiltIns: "usage", //按需加载自动引入
corejs: 3,
}
]
};
开发 Web App 项目,项目一旦处于网络离线情况,就没法访问了。我们希望给项目提供离线体验。 渐进式网络应用程序(progressiveweb application·PWA):是一种可以提供类似于 native app(原生应用程序) 体验的 Web App 的技术。 其中最重要的是,在 离线(offline)时应用程序能够继续运行功能。内部通过 Service Workers 技术实现的。
npm install workbox-webpack-plugin --save-dev
npm run build 现在你可以看到,生成了两个额外的文件:service-worker.js 和名称冗长的 precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js。service-worker.js 是 Service Worker 文件,precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js 是 service-worker.js 引用的文件,所以它也可以运行。你本地生成的文件可能会有所不同,但是应该会有一个 service-worker.js 文件。
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
启动会发现未成功,这个时候要安装server npm i server -g 启动 sever dist [具体可参考](https://www.webpackjs.com/guides/progressive-web-application/#adding-workbox)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。