You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
4.4 KiB
164 lines
4.4 KiB
/**
|
|
* webpack 通用配置
|
|
*/
|
|
const path = require('path'); // path
|
|
const webpack = require('webpack'); // webpack
|
|
const json5 = require('json5'); // json5
|
|
const HtmlWebpackPlugin = require('html-webpack-plugin'); // webpack html 生成插件
|
|
const CopyWebpackPlugin = require('copy-webpack-plugin'); // webpack copy 插件
|
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 抽取 css 插件
|
|
const { VueLoaderPlugin } = require('vue-loader'); // vue loader 插件
|
|
const ESLintPlugin = require('eslint-webpack-plugin'); // eslint 插件
|
|
const packageJson = require('./package.json'); // package.json
|
|
const projectName =packageJson.name; // 项目名称
|
|
|
|
module.exports = {
|
|
// 入口文件
|
|
entry: './src/main',
|
|
// 输出
|
|
output: {
|
|
// 输出路径(为兼容后端和多个前端项目)
|
|
// 1. 兼容后端: 将 dist 目录作为资源目录, 其中 public 种的静态资源可以直接访问
|
|
// 2. 兼容多个前端项目: 每个项目发布到 public 目录下的唯一项目名称目录
|
|
path: path.resolve(__dirname, `dist/public/${projectName}`),
|
|
// 输出文件名
|
|
filename: `javascript/[name].[contenthash:5].js`,
|
|
// 指定发布路径,使用 auto 可具有更多灵活性
|
|
publicPath: 'auto',
|
|
// 每次构建时,首先删除 output.path 目录所有内容,保证每次得到最新的构建结果
|
|
clean: true,
|
|
},
|
|
|
|
module: {
|
|
rules: [
|
|
// babel(包含处理: typescript)
|
|
{
|
|
test: /\.(t|j)s$/,
|
|
exclude: /node_modules/,
|
|
use: [
|
|
{
|
|
loader: "babel-loader",
|
|
options: {
|
|
cacheDirectory: true,
|
|
}
|
|
}
|
|
]
|
|
},
|
|
|
|
// css
|
|
{
|
|
test: /\.(sa|sc|c)ss$/,
|
|
use: [{
|
|
loader: MiniCssExtractPlugin.loader,
|
|
},
|
|
{
|
|
loader: 'css-loader',
|
|
},
|
|
{
|
|
loader: 'postcss-loader',
|
|
}]
|
|
},
|
|
|
|
// 字体文件
|
|
{
|
|
test: /\.(woff|woff2|eot|ttf|otf)(\?.*)?$/,
|
|
type: 'asset/resource',
|
|
generator: {
|
|
filename: `fonts/[name].[contenthash:5].[ext]`,
|
|
}
|
|
},
|
|
|
|
// json5
|
|
{
|
|
test: /\.json$/,
|
|
type: 'json',
|
|
parser: {
|
|
parse: json5.parse,
|
|
},
|
|
},
|
|
|
|
// vue loader
|
|
{
|
|
test: /\.vue$/,
|
|
exclude: /node_modules/,
|
|
use: [
|
|
{
|
|
loader: 'vue-loader',
|
|
}
|
|
]
|
|
},
|
|
],
|
|
},
|
|
|
|
// 插件
|
|
plugins: [
|
|
new webpack.DefinePlugin({
|
|
__VUE_OPTIONS_API__: JSON.stringify(true),
|
|
__VUE_PROD_DEVTOOLS__: JSON.stringify(false)
|
|
}),
|
|
|
|
// 进度显示插件
|
|
new webpack.ProgressPlugin(),
|
|
|
|
// css 抽取插件
|
|
new MiniCssExtractPlugin({
|
|
filename: `css/[name].[contenthash:5].css`,
|
|
chunkFilename: `css/[name].[contenthash:5].css`
|
|
}),
|
|
|
|
// 自动生成静态 index.html 文件
|
|
new HtmlWebpackPlugin({
|
|
template: 'public/index.html',
|
|
filename: `index.html`,
|
|
minify: false,
|
|
inject: 'body',
|
|
timestamp: new Date().getTime(),
|
|
}),
|
|
|
|
// 拷贝静态资源到 output.path 指定的目录
|
|
new CopyWebpackPlugin({
|
|
patterns: [
|
|
{
|
|
from: 'public',
|
|
toType: 'dir',
|
|
filter: async (resourcePath) => {
|
|
// 不复制 index.html 因为 index.html 已经由 HtmlWebpackPlugin 插件生成了
|
|
if (resourcePath.endsWith('/public/index.html') || resourcePath.endsWith('.DS_Store')) {
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
info: { minimized: true },
|
|
}
|
|
]
|
|
}),
|
|
|
|
// vue loader 插件
|
|
new VueLoaderPlugin(),
|
|
|
|
// eslint 插件
|
|
new ESLintPlugin({
|
|
fix: true,
|
|
formatter: 'stylish',
|
|
extensions: ['js', 'ts', 'vue', 'cjs'],
|
|
exclude: [
|
|
'node_modules',
|
|
],
|
|
}),
|
|
],
|
|
|
|
// 配置模块如何被解析,
|
|
resolve: {
|
|
// 设置模块别名,方便引用
|
|
alias: {
|
|
'@': path.resolve(__dirname, 'src'),
|
|
},
|
|
// 设置支持的模块扩展名,即这些扩展名的文件可以作为模块被使用
|
|
extensions: ['.ts', '.js', '.cjs', '.vue'],
|
|
fallback: {
|
|
"fs": false,
|
|
"os": false,
|
|
"path": false,
|
|
}
|
|
},
|
|
};
|
|
|