diff --git a/src/cli/cli.ts b/src/cli/cli.ts index 2ef740e..539a6a2 100644 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -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' @@ -13,9 +13,12 @@ export function run (): void { .version(version, '-v, --version', 'output the version number') .option('-d --rootDir ', 'the directory of project to be transfered') .option('-t --projectType ', 'the type of the project, use vue-cli or webpack') + .option('-e --entry ', '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)) { @@ -25,7 +28,7 @@ export function run (): void { start(config) } -export function start (config : Config): void { +export async function start (config : Config): Promise { console.log('******************* Webpack to Vite *******************') console.log(`Project path: ${config.rootDir}`) @@ -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')) diff --git a/src/config/config.ts b/src/config/config.ts index 4a68ae5..1a363b7 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -1,6 +1,7 @@ export interface Config { rootDir?: string; projectType?: string; + entry?: any; } export interface DevServer { diff --git a/src/generate/geneIndexHtml.ts b/src/generate/geneIndexHtml.ts index 74ac7b2..129fab1 100644 --- a/src/generate/geneIndexHtml.ts +++ b/src/generate/geneIndexHtml.ts @@ -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) } @@ -20,21 +27,53 @@ export function injectHtml (source: string, entries: string[]): string { let body = ' \n' body += '
\n' for (const entry of entries) { - body += `\n` + if (entry !== undefined) { + body += `\n` + } } 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 +} diff --git a/src/generate/geneViteConfig.ts b/src/generate/geneViteConfig.ts index 0f2b2f7..b50b663 100644 --- a/src/generate/geneViteConfig.ts +++ b/src/generate/geneViteConfig.ts @@ -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 { +export async function geneViteConfig (rootDir: string, outDir: string, config: Config): Promise { 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) } diff --git a/src/transform/transformWebpack.ts b/src/transform/transformWebpack.ts index 148d90e..4148dbc 100644 --- a/src/transform/transformWebpack.ts +++ b/src/transform/transformWebpack.ts @@ -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 { @@ -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) { diff --git a/src/utils/common.ts b/src/utils/common.ts new file mode 100644 index 0000000..5bfe391 --- /dev/null +++ b/src/utils/common.ts @@ -0,0 +1,3 @@ +export function isObject (value : any) : boolean { + return Object.prototype.toString.call(value) === '[object Object]'; +}