Skip to content

Commit

Permalink
feat: generate index.html support commander and multiple entries
Browse files Browse the repository at this point in the history
  • Loading branch information
ygj6 committed Jun 30, 2021
1 parent 8058241 commit 7bcbbae
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 25 deletions.
20 changes: 11 additions & 9 deletions src/cli/cli.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path'
import fs from 'fs'
import { genIndexHtml } from '../generate/geneIndexHtml'
import { genePackageJson as genPackageJson } from '../generate/genePackageJson'
import { geneIndexHtml } from '../generate/geneIndexHtml'
import { genePackageJson } from '../generate/genePackageJson'
import { geneViteConfig } from '../generate/geneViteConfig'
import { Command } from 'commander'
import { Config } from '../config/config'
Expand All @@ -13,9 +13,12 @@ export function run (): void {
.version(version, '-v, --version', 'output the version number')
.option('-d --rootDir <path>', 'the directory of project to be transfered')
.option('-t --projectType <type>', 'the type of the project, use vue-cli or webpack')
.option('-e --entry <type>', 'entrance of the entire build process, webpack or vite will start from ' +
'those entry files to build, if no entry file is specified, src/main.ts or src/main.js will be' +
'used as default')
.parse(process.argv)

const keys = ['rootDir', 'projectType']
const keys = ['rootDir', 'projectType', 'entry']
const config: Config = {}
keys.forEach(function (k) {
if (Object.prototype.hasOwnProperty.call(program.opts(), k)) {
Expand All @@ -25,7 +28,7 @@ export function run (): void {
start(config)
}

export function start (config : Config): void {
export async function start (config : Config): Promise<void> {
console.log('******************* Webpack to Vite *******************')
console.log(`Project path: ${config.rootDir}`)

Expand All @@ -37,13 +40,12 @@ export function start (config : Config): void {
const cwd = process.cwd()
const rootDir = path.resolve(config.rootDir)

// TODO:how to deal with the index.html in the project,
// notice that this will not choose the root directory in non-vite projects
genIndexHtml(rootDir)
genePackageJson(path.resolve(rootDir, 'package.json'))

genPackageJson(path.resolve(rootDir, 'package.json'))
await geneViteConfig(rootDir, rootDir, config)

geneViteConfig(rootDir, rootDir, config.projectType)
// generate index.html must be after generate vite.config.js
geneIndexHtml(rootDir, config)

console.log('************************ Done ! ************************')
const pkgManager = fs.existsSync(path.resolve(rootDir, 'yarn.lock'))
Expand Down
1 change: 1 addition & 0 deletions src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface Config {
rootDir?: string;
projectType?: string;
entry?: any;
}

export interface DevServer {
Expand Down
55 changes: 47 additions & 8 deletions src/generate/geneIndexHtml.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import fs from 'fs'
import path from 'path'
import { readSync, writeSync } from '../utils/file'
import { isObject } from '../utils/common'
import { Config } from '../config/config'

export function genIndexHtml (root: string): void {
const filePath = path.resolve(root, 'index.html')
export function geneIndexHtml (rootDir: string, config: Config): void {
const filePath = path.resolve(rootDir, 'index.html')
let htmlContent
if (fs.existsSync(filePath)) {
htmlContent = readSync(filePath)
} else {
htmlContent = readSync(path.resolve(path.resolve('src/template/index.html')))
}
const entries = getVuecliEntries(root)
let entries : string[] = []
if (config.entry !== undefined && config.entry !== '' && config.entry.length !== 0 && config.entry !== {}) {
entries = getEntries(config.entry)
} else {
entries = getDefaultEntries(rootDir)
}
const injectedContent = injectHtml(htmlContent, entries)
writeSync(filePath, injectedContent)
}
Expand All @@ -20,21 +27,53 @@ export function injectHtml (source: string, entries: string[]): string {
let body = ' <body>\n'
body += ' <div id="app"></div>\n'
for (const entry of entries) {
body += `<script type="module" src="${entry}"></script>\n`
if (entry !== undefined) {
body += `<script type="module" src="${entry}"></script>\n`
}
}
body += ' </body>'
const result = source.replace(bodyRegex, body)
return result
}

function getVuecliEntries (root: string): string[] {
const entries = []
const mainFile = path.resolve(root, 'src/main.ts')
function getDefaultEntries (rootDir: string): string[] {
const entries: string[] = []
let mainFile = path.resolve(rootDir, 'src/main.ts')
if (fs.existsSync(mainFile)) {
entries.push('/src/main.ts')
} else {
return entries
}
mainFile = path.resolve(rootDir, 'src/main.js')
if (fs.existsSync(mainFile)) {
entries.push('/src/main.js')
return entries
}
// TODO: vue-cli pages config
return entries
}

function getEntries (entry: any) : string[] {
const entries: string[] = []
if (entry === undefined) {
return entries
}
if (isObject(entry)) {
Object.keys(entry).forEach(function (name) {
entries.push(entry[name])
})
}
if (typeof entry === 'function') {
entries.push(entry())
}
if (typeof entry === 'string') {
entries.push(entry)
}

// vite support hmr by default, so do not need to import webpack-hot-middleware
entries.forEach((item, index) => {
if (item.indexOf('dev-client') !== -1) {
delete (entries[index])
}
})
return entries
}
10 changes: 7 additions & 3 deletions src/generate/geneViteConfig.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import path from 'path'
import { TemplateData } from '../config/config'
import { Config, TemplateData } from '../config/config'
import { getTransformer } from '../transform/transformer'
import { render, serializeObject } from './render'

export async function geneViteConfig (rootDir: string, outDir: string, projectType: string): Promise<void> {
export async function geneViteConfig (rootDir: string, outDir: string, config: Config): Promise<void> {
const template = path.resolve('src/template/vite.config.ejs')
const transformer = getTransformer(projectType)
const transformer = getTransformer(config.projectType)
const viteConfig = await transformer.transform(rootDir)
const configStr = serializeObject(viteConfig)
const data: TemplateData = {
IMPORT_LIST: transformer.context.importers,
USER_CONFIG: configStr
}
// fill entry
if (config.entry === undefined) {
config.entry = transformer.context.config.build.rollupOptions.input
}

render(outDir, template, data)
}
7 changes: 2 additions & 5 deletions src/transform/transformWebpack.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import path from 'path'
import { parseWebpackConfig } from '../config/parse'
import { RawValue, ViteConfig } from '../config/vite'
import { TransformContext } from './context'
import { initViteConfig, Transformer, transformImporters } from './transformer'
import path from 'path'
import { DEFAULT_VUE_VERSION } from '../constants/constants'
import { Entry } from '../config/webpack'
import { isObject } from '../utils/common'

// convert webpack.config.js => vite.config.js
export class WebpackTransformer implements Transformer {
Expand Down Expand Up @@ -75,10 +76,6 @@ export class WebpackTransformer implements Transformer {
}
}

function isObject (value : any) : boolean {
return Object.prototype.toString.call(value) === '[object Object]';
}

function suitableFormat (entry: Entry) : Entry {
const res : Entry = {}
Object.keys(entry).forEach(function (name) {
Expand Down
3 changes: 3 additions & 0 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isObject (value : any) : boolean {
return Object.prototype.toString.call(value) === '[object Object]';
}

0 comments on commit 7bcbbae

Please sign in to comment.