2022/01/[Varlet]实战篇_这不就跑起来了/index

写在前面

相信已经有不少小伙伴们已经实现了自己cli工具的gen命令了。

接下来我们来讲讲如何实现一个dev命令,并通过dev命令来启动项目。

准备工作

有了前面几篇的铺垫,到这里相信同学们已经知道接下来我要做什么了。

我们回到src/index.ts,写下

1
program.command('dev').description('Run varlet development environment').action(dev)

用来接收一个dev命令,而具体要做的处理,我们一样放在src/commands/dev中,对外暴露一个dev方法。

dev要做的事

我们先手动将运行环境切换为dev

1
process.env.NODE_ENV = 'development'

然后我们需要确保输入名称的地方存在项目文件

1
2
const SRC_DIR = resolve(process.cwd(), 'src')
ensureDirSync(SRC_DIR)

当完成以上工作后,就可以启动项目了。

startServer

我们用一个startServer函数来处理启动的业务逻辑。

1
2
3
4
5
6
7
let server

const startServer = async () =>{
server = await createServer()
await server.listen()
server.printUrls()
}

到这里,我们就可以将服务启动起来了。

image.png

我们访问一下http://localhost:3000/

image.png

肯定会有同学们疑惑了,我服务不是起来了吗,怎么访问不到呢?

其实啊很简单,因为我们没有进行站点的构建,所以没法访问对应的站点资源。

举个例子,我们在cli创建的的项目根目录,新建一个index.html,然后看看浏览器这边是不是就可以正常显示了呢。

既然知道了这个问题,那我们接下来就来完成站点的构建。

站点构建

我们定义一个buildSiteEntry函数用于处理站点构建。

image.png

varlet-cli的源码中,我们可以看出buildSiteEntry一共做了三件事

1 构建移动端站点的路由

2 构建pc端站点的路由

3 生成站点资源

本文我们以1为例进行剖析,对2感兴趣的小伙伴们可以访问我们的代码仓库进行查看。

image.png

从图中我们可以分析出来,我们需要将每个组件下exampleindex.vue作为页面,添加到路由中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 获取src目录下的文件
const dir: string[] = await readdir('src')

// 拼接页面地址
const buildPath = (filename: string) => resolve('src', filename, 'example', 'index.vue')

// 判断是否存在对应地址
const existPath = (filename: string) => pathExistsSync(buildPath(filename))

// 通过slash转换`/`
const slashPath = (filename: string) => slash(buildPath(filename))

// 生成地址
const examplePaths = dir.filter(existPath).map(slashPath)

image.png

从上面我们拿到了所有的页面地址,接下来就是填充route

1
2
3
4
5
6
7
8
9
10
11
12
13
 const routes = examplePaths.map(
(examplePath) => `
{
path: '${'/' + examplePath.match(//([-\w]+)/example/index.vue/)?.[1]}',
// @ts-ignore
component: () => import('${examplePath}')
}\
`
)

const source = `export default [\
${routes.join(',')}
]`

image.png

至此我们就完成了路由的动态创建,接下来就是文件写入了。

我们创建一个outputFileSyncOnChange用于处理问文件写入

1
2
3
4
5
6
7
const outputFileSyncOnChange = (path: string, code: string) => {
ensureFileSync(path)
const content = readFileSync(path, 'utf-8')
if (content !== code) {
outputFileSync(path, code)
}
}

接下来 我们调用outputFileSyncOnChange函数,将路由写入到文件中。

1
outputFileSyncOnChange(resolve(process.cwd(), '.varlet/mobile.routes.ts'), source)

接下来就是站点文件的生成。

我们将site文件夹(存放的站点文件)拷贝到当前运行的目录下。

1
copy(resolve(__dirname, '../../site'), resolve(process.cwd(), '.varlet/site'))

接下来,我们添加一些vite的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const inlineConfig =  {
root: resolve(process.cwd(), '.varlet/site'),
resolve: {
extensions:['.vue', '.tsx', '.ts', '.jsx', '.js', '.less', '.css'],
alias: {'@config': resolve(process.cwd(), '.varlet/site.config.json'),
'@pc-routes': resolve(process.cwd(), '.varlet/pc.routes.ts'),
'@mobile-routes': resolve(process.cwd(), '.varlet/mobile.routes.ts') },
},
plugins: [
vue({
include: [/.vue$/, /.md$/],
}),
md({ style: 'highlight.style' }),
],
}

server = await createServer(inlineConfig)

然后我们通过you-cli-name dev重新跑一遍。

image.png

这不就跑起来了嘛~

最后

以上就是dev命令的相关内容了,跟varlet-clidev相比有一些删减。

更详细的内容请移步我们的代码仓库,欢迎star && pr

文章作者: Joker
文章链接: https://qytayh.github.io/2022/01/[Varlet]%E5%AE%9E%E6%88%98%E7%AF%87_%E8%BF%99%E4%B8%8D%E5%B0%B1%E8%B7%91%E8%B5%B7%E6%9D%A5%E4%BA%86/index/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Joker's Blog