Skip to content

Commit

Permalink
feat(cli/site): support hmr
Browse files Browse the repository at this point in the history
affects: varlet-cli-playground, @varlet/cli
  • Loading branch information
haoziqaq committed Jul 28, 2021
1 parent c1696fe commit 5ff00d6
Show file tree
Hide file tree
Showing 17 changed files with 198 additions and 145 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules

.varlet
.idea
.vscode
*.log
Expand Down
1 change: 0 additions & 1 deletion packages/varlet-cli-playground/docs/home.en-US.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
### Intro
123123
Varlet is a Material design mobile component library developed based on `Vue3`, developed and maintained by partners in the community.

### Features
Expand Down
2 changes: 1 addition & 1 deletion packages/varlet-cli-playground/varlet.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
useMobile: true,
useMobile: false,
pc: {
menu: [
{
Expand Down
1 change: 1 addition & 0 deletions packages/varlet-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"babel-jest": "^26.6.3",
"babel-loader": "^8.1.0",
"chalk": "^4.1.0",
"chokidar": "^3.5.2",
"clean-webpack-plugin": "^3.0.0",
"clipboard": "^2.0.6",
"commander": "^6.2.0",
Expand Down
7 changes: 0 additions & 7 deletions packages/varlet-cli/src/commands/build.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import webpack from 'webpack'
import logger from '../shared/logger'
import { ensureDirSync } from 'fs-extra'
import { buildMobileSiteRoutes, buildPcSiteRoutes } from '../compiler/compileRoutes'
import { getBuildConfig } from '../config/webpack.build.config'
import { SRC_DIR } from '../shared/constant'
import { getVarletConfig } from '../config/varlet.config'
import { setAlias } from '../config/webpack.base.config'

export async function build() {
ensureDirSync(SRC_DIR)

const config = getBuildConfig()
const [mobileRouteId, pcRouteId] = await Promise.all([buildMobileSiteRoutes(), buildPcSiteRoutes()])
const { configId } = getVarletConfig()

setAlias(config, { pcRouteId, mobileRouteId, configId })

webpack(config, (err, stats) => {
err && logger.error(err.toString())
Expand Down
2 changes: 1 addition & 1 deletion packages/varlet-cli/src/commands/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DOCS_DIR_NAME, EXAMPLE_DIR_NAME, SRC_DIR, TESTS_DIR_NAME } from '../sha
import { getVarletConfig } from '../config/varlet.config'
import { get } from 'lodash'

const { varletConfig } = getVarletConfig()
const varletConfig = getVarletConfig()

export async function create(name: string) {
const namespace = get(varletConfig, 'namespace')
Expand Down
8 changes: 0 additions & 8 deletions packages/varlet-cli/src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import logger from '../shared/logger'
import { getPort } from 'portfinder'
import { ensureDirSync } from 'fs-extra'
import { getDevConfig } from '../config/webpack.dev.config'
import { buildMobileSiteRoutes, buildPcSiteRoutes } from '../compiler/compileRoutes'
import { SRC_DIR } from '../shared/constant'
import { setAlias } from '../config/webpack.base.config'
import { getVarletConfig } from '../config/varlet.config'

export function runDevServer(port: number, config: any) {
const { host } = config.devServer
Expand All @@ -30,11 +27,6 @@ export async function dev() {
ensureDirSync(SRC_DIR)

const config = getDevConfig()
const [mobileRouteId, pcRouteId] = await Promise.all([buildMobileSiteRoutes(), buildPcSiteRoutes()])
const { configId } = getVarletConfig()

setAlias(config, { pcRouteId, mobileRouteId, configId })

const { port } = config.devServer
getPort(
{
Expand Down
53 changes: 34 additions & 19 deletions packages/varlet-cli/src/compiler/compileRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import slash from 'slash'
import hash from 'hash-sum'
import {
DOCS_DIR_NAME,
EXAMPLE_DIR_INDEX,
EXAMPLE_DIR_NAME,
ROOT_DOCS_DIR,
SITE_DOCS_GLOB,
SITE_EXAMPLE_GLOB,
SITE_MOBILE_ROUTES,
SITE_PC_ROUTES,
SRC_DIR,
SITE_PC,
SITE_MOBILE,
VARLET_CONFIG,
} from '../shared/constant'
import { pathExistsSync, readdir, readdirSync, writeFile } from 'fs-extra'
import { pathExistsSync, readdir, readdirSync } from 'fs-extra'
import { resolve } from 'path'
import { isMD } from '../shared/fsUtils'
import { isMD, outputFileSyncOnChange } from '../shared/fsUtils'
import { getVarletConfig } from '../config/varlet.config'
import chokidar from 'chokidar'
import type { Compiler } from 'webpack'
import type { FSWatcher } from 'chokidar'

const EXAMPLE_COMPONENT_NAME_RE = /\/([-\w]+)\/example\/index.vue/
const COMPONENT_DOCS_RE = /\/([-\w]+)\/docs\/([-\w]+)\.md/
Expand Down Expand Up @@ -82,7 +88,7 @@ export async function findRootDocsPaths(): Promise<string[]> {
return dir.filter(existPath).map(slashPath)
}

export async function buildMobileSiteRoutes(): Promise<string> {
export async function buildMobileSiteRoutes() {
const examplePaths: string[] = await findExamplePaths()

const routes = examplePaths.map(
Expand All @@ -98,16 +104,10 @@ export async function buildMobileSiteRoutes(): Promise<string> {
${routes.join(',')}
]`

const mobileRouteId = hash(source)

const path = resolve(SITE_MOBILE, `./${mobileRouteId}.routes.ts`)

await writeFile(path, source)

return mobileRouteId
await outputFileSyncOnChange(SITE_MOBILE_ROUTES, source)
}

export async function buildPcSiteRoutes(): Promise<string> {
export async function buildPcSiteRoutes() {
const [componentDocsPaths, rootDocsPaths] = await Promise.all([findComponentDocsPaths(), findRootDocsPaths()])

const componentDocsRoutes = componentDocsPaths.map(
Expand All @@ -134,11 +134,26 @@ export async function buildPcSiteRoutes(): Promise<string> {
${[...componentDocsRoutes, rootDocsRoutes].join(',')}
]`

const pcRouteId = hash(source)

const path = resolve(SITE_PC, `./${pcRouteId}.routes.ts`)
outputFileSyncOnChange(SITE_PC_ROUTES, source)
}

await writeFile(path, source)
export async function buildSiteEntry() {
getVarletConfig()
await Promise.all([buildMobileSiteRoutes(), buildPcSiteRoutes()])
}

return pcRouteId
const PLUGIN_NAME = 'VarletSitePlugin'

export class VarletSitePlugin {
apply(compiler: Compiler) {
if (process.env.NODE_ENV === 'production') {
compiler.hooks.beforeCompile.tapPromise('VarletSitePlugin', buildSiteEntry)
} else {
const watcher: FSWatcher = chokidar.watch([SITE_EXAMPLE_GLOB, SITE_DOCS_GLOB, VARLET_CONFIG])
compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, async () => {
watcher.on('add', buildSiteEntry).on('unlink', buildSiteEntry).on('change', buildSiteEntry)
await buildSiteEntry()
})
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { isDir, isMD } from '../shared/fsUtils'
import { get } from 'lodash'
import { getVarletConfig } from '../config/varlet.config'

const { varletConfig } = getVarletConfig()
const varletConfig = getVarletConfig()

const TABLE_HEAD_RE = /\s*\|.*\|\s*\n\s*\|.*---+\s*\|\s*\n+/
const TABLE_FOOT_RE = /(\|\s*$)|(\|\s*\n(?!\s*\|))/
Expand Down
26 changes: 12 additions & 14 deletions packages/varlet-cli/src/config/varlet.config.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { pathExistsSync, writeFileSync } from 'fs-extra'
import hash from 'hash-sum'
import { resolve } from 'path'
import { pathExistsSync } from 'fs-extra'
import { merge } from 'lodash'
import { VARLET_CONFIG, SITE } from '../shared/constant'
import { VARLET_CONFIG, SITE_CONFIG } from '../shared/constant'
import { outputFileSyncOnChange } from '../shared/fsUtils'

export function getVarletConfig() {
const config = (pathExistsSync(VARLET_CONFIG) && require(VARLET_CONFIG)) || {}
const mergedConfig = merge(require('../../varlet.default.config.js'), config)
const source = JSON.stringify(mergedConfig, null, 2)
let config = {}

const configId = hash(source)
const path = resolve(SITE, `./${configId}.site.config.json`)
if (pathExistsSync(VARLET_CONFIG)) {
delete require.cache[require.resolve(VARLET_CONFIG)]
config = require(VARLET_CONFIG)
}

writeFileSync(path, source)
const mergedConfig = merge(require('../../varlet.default.config.js'), config)
const source = JSON.stringify(mergedConfig, null, 2)
outputFileSyncOnChange(SITE_CONFIG, source)

return {
varletConfig: mergedConfig,
configId,
}
return mergedConfig
}
157 changes: 76 additions & 81 deletions packages/varlet-cli/src/config/webpack.base.config.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import {
EXTENSIONS,
POSTCSS_CONFIG,
SITE,
SITE_MOBILE,
SITE_CONFIG,
SITE_MOBILE_MAIN,
SITE_PC,
SITE_MOBILE_ROUTES,
SITE_PC_MAIN,
SITE_PC_ROUTES,
TS_CONFIG,
} from '../shared/constant'
import { ForkTsCheckerWebpackPlugin } from 'fork-ts-checker-webpack-plugin/lib/ForkTsCheckerWebpackPlugin'
import { VueLoaderPlugin } from 'vue-loader'
import { pathExistsSync } from 'fs-extra'
import { WebpackPluginInstance } from 'webpack'
import { resolve } from 'path'
import { createPostcssOptions } from './postcss.config'

export const CSS_LOADERS = [
Expand Down Expand Up @@ -48,89 +47,85 @@ export function createBasePlugins(): WebpackPluginInstance[] {
return plugins
}

export function getBaseConfig() {
return {
entry: {
pc: SITE_PC_MAIN,
mobile: SITE_MOBILE_MAIN,
},
resolve: {
extensions: EXTENSIONS,
alias: {},
export const BASE_CONFIG = {
entry: {
pc: SITE_PC_MAIN,
mobile: SITE_MOBILE_MAIN,
},
resolve: {
extensions: EXTENSIONS,
alias: {
'@config': SITE_CONFIG,
'@pc-routes': SITE_PC_ROUTES,
'@mobile-routes': SITE_MOBILE_ROUTES,
},
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader'],
},
{
test: /\.(js|ts)$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-typescript'],
plugins: ['@babel/plugin-transform-runtime', '@babel/plugin-transform-typescript'],
},
},
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader'],
},
{
test: /\.(js|ts)$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-typescript'],
plugins: ['@babel/plugin-transform-runtime', '@babel/plugin-transform-typescript'],
},
],
exclude: /node_modules/,
},
{
test: /\.md$/,
use: ['vue-loader', '@varlet/markdown-loader'],
},
{
test: /\.(png|jpg|gif|jpeg|svg)$/,
type: 'asset',
generator: {
filename: 'images/[hash][ext][query]',
},
},
{
test: /\.(eot|ttf|woff|woff2)$/,
type: 'asset',
generator: {
filename: 'fonts/[hash][ext][query]',
},
},
{
test: /\.(mp3|wav|ogg|acc)$/,
type: 'asset/resource',
generator: {
filename: 'audio/[hash][ext][query]',
},
],
exclude: /node_modules/,
},
{
test: /\.md$/,
use: ['vue-loader', '@varlet/markdown-loader'],
},
{
test: /\.(png|jpg|gif|jpeg|svg)$/,
type: 'asset',
generator: {
filename: 'images/[hash][ext][query]',
},
{
test: /\.(mp4|webm)$/,
type: 'asset/resource',
generator: {
filename: 'video/[hash][ext][query]',
},
},
{
test: /\.(eot|ttf|woff|woff2)$/,
type: 'asset',
generator: {
filename: 'fonts/[hash][ext][query]',
},
{
test: /\.css$/,
use: CSS_LOADERS,
},
{
test: /\.(mp3|wav|ogg|acc)$/,
type: 'asset/resource',
generator: {
filename: 'audio/[hash][ext][query]',
},
{
test: /\.less$/,
use: [...CSS_LOADERS, 'less-loader'],
},
{
test: /\.(mp4|webm)$/,
type: 'asset/resource',
generator: {
filename: 'video/[hash][ext][query]',
},
],
},
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename],
},
{
test: /\.css$/,
use: CSS_LOADERS,
},
{
test: /\.less$/,
use: [...CSS_LOADERS, 'less-loader'],
},
],
},
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename],
},
plugins: createBasePlugins(),
}
}

export function setAlias(config: any, { pcRouteId, mobileRouteId, configId }: Record<string, string>) {
config.resolve.alias['@pc-routes'] = resolve(SITE_PC, `./${pcRouteId}.routes.ts`)
config.resolve.alias['@mobile-routes'] = resolve(SITE_MOBILE, `./${mobileRouteId}.routes.ts`)
config.resolve.alias['@config'] = resolve(SITE, `./${configId}.site.config.json`)
}
},
plugins: createBasePlugins(),
} as any
Loading

0 comments on commit 5ff00d6

Please sign in to comment.