多页面项目配置百度有好多,但是没找到符合自己实际开发需求的。于是在春节期间自己捣腾了一个,在此分享。(不足之处还望大家斧正) 多页面配置有好多,但是最终打包的时候在dist目录中都混到了一起,而且不能按需打包。感觉这种模式不是在实际项目开发种想要的,故而对以上痛点做了调整。
1. 目录
├── package.json
├── public
│ ├── favicon.ico
│ └── index.html //多页面入口文件
dist // 打包后项目目录
├── page1
│ ├── index.html
│ └── static
│ └── js
│ ├── index-9db47fe5.js
│ └── vendor-602fa68c.js
└── page2
│ ├── index.html
│ └── static
│ └── js
│ ├── index-dd26faef.js
│ └── vendor-719f3429.js
├── scripts
│ ├── build.js // 打包工具函数
│ ├── createPages.js // 创建多页面目录工具函数
│ └── templates // 模板目录
│ ├── morePages // 多页面模板
│ │ ├── App.vue
│ │ ├── index.html
│ │ └── main.ts
│ └── srcHtml.ejs // 多页面入口文件模板
├── src
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ └── HelloWorld.vue
│ ├── env.d.ts
│ └── pages // 多页面项目目录
│ ├── page1 // 项目
│ │ ├── App.vue
│ │ ├── index.html
│ │ └── main.ts
│ └── page2 // 项目
│ ├── App.vue
│ ├── index.html
│ └── main.ts
├── tsconfig.json
├── vite.config.ts // 多页面配置文件
2. vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
// 打包工具函数
import build from "./scripts/build";
export default defineConfig(async ({ command, mode }) => {
let pagesDir;
// 选择要打包的多页面项目
if (mode !== "development") {
await build.main();
pagesDir = build.pageName;
}
return {
plugins: [vue()],
root: `./src/pages`,
base: `http://www.xxx.com`,
publicDir:`${process.cwd()}/public`,
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
components: path.resolve(__dirname, "src/components"),
},
dedupe: [],
// 情景导出package.json 配置中的 exports 字段
conditions: [],
// 解析package.json 中的字段
mainFields: ["module", "jsnext:main", "jsnext"],
// 导入时想要省略的扩展名列表
extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"],
},
clearScreen: false,
build: {
// 浏览器兼容性 ‘esnext’ | 'modules'
target: "modules",
//输出路径
outDir: `${process.cwd()}/dist/`,
// 小于此阈值的导入或引用资源将内联为 base64 编码, 以避免额外的http请求, 设置为 0, 可以完全禁用此项,
assetsInlineLimit: 4096,
// 启动 / 禁用 CSS 代码拆分
cssCodeSplit: true,
// 构建后是否生成 soutrce map 文件
sourcemap: false,
// 自定义底层的 Rollup 打包配置
rollupOptions: {
input: path.resolve(`src/pages/${pagesDir}/index.html`),
output: {
chunkFileNames: `${pagesDir}/static/js/[name]-[hash].js`,
entryFileNames: `${pagesDir}/static/js/[name]-[hash].js`,
assetFileNames: `${pagesDir}/static/[ext]/[name]-[hash].[ext]`,
},
},
},
};
});
3. 打包工具函数
import { readdir } from "fs/promises";
import { resolve } from "path";
// 命令行交互工具函数
import inquirer from "inquirer";
class Build {
constructor() {
this.pagesPath = resolve("src/pages");
}
async main() {
// 读取pages 项目目录并存储
await this.setData();
// 命令行交互(选择打包的项目)
await this.selectBuildName();
}
async setData() {
const pagesDir = await readdir(this.pagesPath);
const choices = pagesDir.map((item) => `${item} => 多页面项目`);
this.questions = [
{
type: "rawlist",
name: "page",
message: "选择要打包的项目",
choices,
},
];
}
selectBuildName() {
return inquirer.prompt(this.questions).then(async (answers) => {
const { page } = answers;
const pageName = page.split("=>")[0].trim();
this.pageName = pageName;
});
}
}
export default new Build();
4. 创建多页面目录工具函数
import { mkdir, readFile, writeFile, readdir } from "fs/promises";
import { resolve } from "path";
import chalk from "chalk";
import ejs from "ejs";
class CreatePages {
constructor() {
this.pagesPath = resolve("src/pages");
this.pageName = process.argv[2];
this.mkPageDir();
}
// 1 创建目录
mkPageDir() {
if(!this.pageName) return this.log(["red", `未输入创建项目的名称`]);
mkdir(`${this.pagesPath}/${this.pageName}`)
.then(() => {
this.log(["green", `项目创建成功!`]);
this.createFile();
this.rewriteSrcHtml();
})
.catch((e) => {
this.log(["red", e.message]);
});
}
// 2 复制文件
createFile() {
["main.ts", "index.html", "App.vue"].forEach(async (item) => {
try {
const fileStr = await readFile(
`./scripts/templates/morePages/${item}`,
"utf-8"
);
await writeFile(`${this.pagesPath}/${this.pageName}/${item}`, fileStr, "utf-8");
this.log(["green", `${item} 文件创建成功!`]);
} catch (e) {
this.log(["red", e.message]);
}
});
}
// 3 根目录index.html 中插入 多页面入口
async rewriteSrcHtml() {
const pagesDir = await readdir(this.pagesPath);
ejs
.renderFile("./scripts/templates/srcHtml.ejs", { pagesDir })
.then((res) => {
return writeFile(`${resolve("public")}/index.html`, res, "utf-8");
})
.then(() => {
this.log(["green", "多页面入口文件创建成功!"]);
})
.catch((e) => {
this.log(["red", e.message]);
});
}
log([key, value]) {
try {
console.log(chalk[key](`\n => ${value}`));
} catch (e) {
console.log(chalk.red(`\n => ${e.message} \n`));
}
}
}
new CreatePages();
5.创建多页面配置命令
// package.json
"scripts": {
"dev": "vite --host",
"beta": "vite build --mode=beta",
"build": "vite build",
"preview": "vite preview",
"mkpage": "node ./scripts/createPages" // 创建命令
},
yarn mkpage page1(项目名称)
6. 按需打包
MacBook-Pro vite-pages % yarn build
yarn run v1.22.17
warning package.json: No license field
$ vite build
? 选择要打包的项目
1) page1 => 多页面项目
2) page2 => 多页面项目
Answer:
项目地址: gitee.com/whplove/vit…