likes
comments
collection
share

vite多页应用配置

作者站长头像
站长
· 阅读数 19

前言

最近项目的技术栈转到vue3 + vite + ts,有着一定的定制化构建需求,因此才有了以下实践。

目录结构

目前的构建需求是:一套配置+多模块页面输出。目录结构大致如下:

├─.vscode
├─dist
│    ├─one // 打包后的页面1
│    └─two // 打包后的页面2
├─public
├─src
│    ├─one // 模块页面1
│    │  ├─assets
│    │  ├─components
│    │  ├─App.vue
│    │  ├─index.html
│    │  └─main.js
│    └─two // 模块页面2
├─.gitignore
├─package.json
├─README.md
└─vite.config.js

dist目录为打包后的输出目录,通过script构建打包的需求是:

可以指定模块1单独打包,如:

npm run build --project=one

也可以一次性打包所有模块,如:

npm run build:all

单模块页面构建

vite借助于rollup打包,入口文件是项目根目录下的index.html。项目的单模块页面打包时,走的还是默认的vite.config.js配置,不过适当做了修改。

构建时首先需要指明打包的模块名称:

npm run build --project=one

通过命令行来构建时,process.env会自动添加自定义参数npm_config_[project],从而在配置文件中可以获取构建的模块名称以及入口文件的路径:

const npm_config_project = process.env['npm_config_project']
if (!npm_config_project) {
  throw new Error(
    '缺少指定模块!, 如果是构建指定模块,请使用 --project=[module_name]'
  )
}
// 入口文件
const input = resolve(__dirname, `src/${npm_config_project}/index.html`)

在默认的config配置中需要修改三个地方,分别为:

  • 根目录root。配置文件默认的根目录为/,是默认index.html所在目录。但这里的入口文件已经分布在每个子模块页面下,因此需要修改至对应的子模块下。

  • 入口文件input。同上,入口文件为对应子模块页面下的index.html

  • 打包出口output.dir。修改此处,是将构建产物打包至指定目录。如果不指定,则默认是在子模块下。

config需要修改的配置大致如下:

export default defineConfig({
  root: `./src/${npm_config_project}`,
  build: {
    rollupOptions: {
      input,
      output: {
        dir: `dist/${npm_config_project}`
      }
    }
  }
})

如果需要归类同类型文件,还可以修改output.assetFileNamesoutput.chunkFileNames以及output.entryFileNames三个选项。尤其是output.assetFileNames,可以再次分类,

const IMAGE_EXT = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.bmp', '.tiff']
const CSS_EXT = ['.css', '.less', '.sass', '.scss', '.stylus']
assetFileNames: assetInfo => {
    let dir = ''
    if (CSS_EXT.includes(path.extname(assetInfo.name))) {
        dir = 'css'
    } else if (IMAGE_EXT.includes(path.extname(assetInfo.name))) {
        dir = 'images'
    } else {
        dir = 'js'
    }
    return `assets/${dir}/[name].[hash].[extname]`
}

打包后的目录结构如下:

├─dist
│    ├─one
│    │  ├─css
│    │  ├─js
│    │  ├─images
│    │  └─index.html
│    └─two

多模块一次性构建

vite官网给出了多页应用模式配置,而项目里面则是借助于vite中提供的build函数实现的。脚本具体如下:

const build_all = async () => {
  const pagesDir = join(__dirname, '../src');
  const pageDirs = readdirSync(pagesDir, { withFileTypes: true })
    .filter((dir) => dir.isDirectory())
    .map((dir) => dir.name);

  for (const dir of pageDirs) {
    const entry = join(pagesDir, dir, 'index.html');
    const outDir = join(__dirname, '../dist', dir);

    await build({
      root: join(__dirname, '../src', dir),
      plugins: [vue()],
      resolve: {
        alias: {
          '@': fileURLToPath(new URL('./src', import.meta.url)),
        },
      },
      build: {
        outDir,
        emptyOutDir: true,
      },
      rollupOptions: {
        input: entry,
        output: {
          dir: `dist/${dir}`,
          assetFileNames: '[ext]/[name]-[hash].[ext]',
          chunkFileNames: 'js/[name]-[hash].js',
          entryFileNames: 'js/[name]-[hash].js',
        },
      },
    });
    console.log(`built ${dir} successfully!`);
  }
};

build_all().catch((error) => {
  console.error(error);
  process.exit(1);
});

说明:

  • 因为项目是基于ESM的,因此脚本中无法直接使用魔术变量__dirname,而是借助于path中的dirname方法包装了下
const __dirname = dirname(fileURLToPath(import.meta.url));
  • 构建时,可以封装在build.js中,通过执行 node build.js来一次性输出所有模块页面。也可以在package.json中写条相应脚本以方便执行。

总结

一通乱造,也算是基本实现了项目构建需求。

如果大佬们有更简洁更好的配置,可以一起see下、学习下。

拜了个拜O(∩_∩)O哈哈~

转载自:https://juejin.cn/post/7244435485174595641
评论
请登录