Skip to content

参考日期js库date-fns的github

导出的入口文件是由脚本生成的

封装工具库或是组件库时,我们需要追求按需导出按需导入,支持tree-shaking的esm模式

关于esm如何支持tree-shaking- treeShaking原理

👇 导出的文件内容需要是这种语句

js
// This file is generated automatically by `scripts/build/indices.ts`. 
export { default as add } from './add/index'
export { default as addBusinessDays } from './addBusinessDays/index'
export { default as addDays } from './addDays/index'
// ...

node不能直接运行ts,如何在node环境使用ts?

让node直接运行ts

ts
#!/usr/bin/env yarn ts-node

/**
 * @file
 * The script generates index files for submodules.
 */

import { writeFile } from 'fs/promises' //  TODO: node内置模块promises?
import getFileList from '../_lib/getFileList'

interface File {
  name: string
  path: string
  fullPath: string
}

// 传入目录信息生成文件内容
function generateIndex(
  files: File[],
): string {
  // 根据目录信息写入js语句
  const lines = files.map(
    (file) => `export { default as ${file.name} } from '${file.path}/index'`
  )

  // 添加注释和换行
  return `// This file is generated automatically by \`scripts/build/indices.ts\`.

${lines.join('\n')}
`
}

// 立即执行函数
;(async () => {
  // 生成目录信息
  const fileList = await getFileList()

  writeFile('src/index.ts', generateIndex(fileList))
})()

👇 根据src文件夹生成目录信息

js
// lib/getFileList
const path = require('path')
const fs = require('fs')
const { promisify } = require('util') // promisify把node内置模块方法转为promise...用node同步方法不就行了吗..

const exists = promisify(fs.exists)
const readDir = promisify(fs.readdir)

const ignorePattern = /^_|\./ // can't start with `_` or have a `.` in it
const ignoredDirs = ['locale', 'esm', 'fp', 'constants']

async function getFileList() {
  const srcPath = path.join(process.cwd(), 'src')
  const files = await readDir(srcPath)

  // 根据目录生成路径信息
  return Promise.all(
    files
      .filter(
        // 过滤忽略目录
        (file) => !ignorePattern.test(file) && !ignoredDirs.includes(file)
      )
      .map(async (file) => {
        // 存在ts就使用ts,否则输入js的目录
        const isTs = await exists(path.join(srcPath, file, 'index.ts'))

        return {
          name: file,
          path: `./${file}`,
          fullPath: `./src/${file}/index.${isTs ? 'ts' : 'js'}`,
        }
      })
  )
}

module.exports = getFileList

生成组件库目录同理如👇 TODO: