Skip to content

Commit

Permalink
chore: init framework
Browse files Browse the repository at this point in the history
  • Loading branch information
ygj6 committed Jun 11, 2021
1 parent 2fbc2f9 commit 2d130b6
Show file tree
Hide file tree
Showing 35 changed files with 9,175 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
.idea/
node_modules/
tests/out
dist
.settings
yarn.lock
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## webpack-to-vite
transfer a webpack project to vite project
convert a webpack project to a vite project

## Quick start

Expand All @@ -20,7 +20,7 @@ with yarn, run
yarn
yarn build
```
3. transfer
3. convert
```
node ./bin/index --rootDir <project path>
```
Expand Down
4 changes: 4 additions & 0 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node
const cli = require('../dist/cli/cli.js')

cli.run()
10 changes: 10 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
roots: [
"<rootDir>/tests"
],
testRegex: 'tests/(.+)\\.test\\.(jsx|tsx?)$',
transform: {
"^.+\\.(ts|tsx)?$" : "ts-jest"
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
}
8,021 changes: 8,021 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "webpack-to-vite",
"version": "0.0.1",
"description": "convert a webpack project to a vite project",
"main": "bin/index.js",
"scripts": {
"build": "tsc -p tsconfig.json",
"test": "jest",
"test-c": "jest-coverage",
"lint": "eslint --ext .js,.ts src/"
},
"repository": {
"type": "git",
"url": "git+https://github.com/originjs/webpack-to-vite.git"
},
"keywords": [
"vite",
"webpack",
"vue-cli"
],
"author": "ygj6",
"license": "ISC",
"bugs": {
"url": "https://github.com/originjs/webpack-to-vite/issues"
},
"homepage": "https://github.com/originjs/webpack-to-vite#readme",
"devDependencies": {
"@types/ejs": "^3.0.6",
"@types/jest": "^26.0.23",
"@types/jscodeshift": "^0.11.0",
"@types/webpack": "^4.41.26",
"@types/webpack-merge": "^4.1.5",
"@typescript-eslint/eslint-plugin": "^4.26.1",
"@typescript-eslint/parser": "^4.26.1",
"eslint": "^7.28.0",
"jest": "^27.0.4",
"lint-staged": "^11.0.0",
"prettier": "^2.3.1",
"ts-jest": "^27.0.3",
"typescript": "^4.3.2",
"vite": "^2.3.7",
"vite-plugin-env-compatible": "^1.0.0",
"vite-plugin-vue2": "^1.6.2",
"yorkie": "^2.0.0"
},
"dependencies": {
"commander": "^7.2.0",
"ejs": "^3.1.6",
"jscodeshift": "^0.12.0",
"lodash": "^4.17.21",
"webpack-chain": "6.3.1",
"webpack-merge": "4.2.2",
"yargs": "^17.0.1"
}
}
61 changes: 61 additions & 0 deletions src/cli/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import path from "path";
import fs from "fs";
import { genIndexHtml } from "../generate/geneIndexHtml";
import { genePackageJson as genPackageJson } from "../generate/genePackageJson";
import { geneViteConfig } from "../generate/geneViteConfig";
import { Command } from "commander";
import { Config } from "../config/config";

export function run() {
const program = new Command();
program
.version("0.0.1")
.option("--rootDir <path>", "the directory of project to be transfered")
.parse(process.argv);

const keys = ['rootDir'];
const config: Config = {};
keys.forEach(function (k) {
if (Object.prototype.hasOwnProperty.call(program.opts(), k)) {
config[k] = program.opts()[k];
}
});
start(config.rootDir);
}

export function start(rootDir: string) {
console.log("******************* Webpack to Vite *******************");
console.log(`project path: ${rootDir}`);

const cwd = process.cwd();
if (!fs.existsSync(rootDir)) {
console.error(`project path is not correct : ${rootDir}`);
return;
}

rootDir = path.resolve(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);

genPackageJson(path.resolve(rootDir, "package.json"));

geneViteConfig(path.resolve(rootDir, "vue.config.js"), rootDir);

console.log("************************ Done ! ************************");
const pkgManager = fs.existsSync(path.resolve(rootDir, "yarn.lock"))
? "yarn"
: "npm";

console.log("Now please run:\n");
if (rootDir !== cwd) {
console.log(`cd ${path.relative(cwd, rootDir)}`);
}

console.log(`${pkgManager == "yarn" ? "yarn" : "npm install"}`);
console.log(
`${pkgManager === "yarn" ? "yarn serve-vite" : "npm run serve-vite"}`
);
console.log();
}
18 changes: 18 additions & 0 deletions src/config/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface Config {
rootDir?: string;
}

export interface DevServer {
contentBase?: string;
https?: boolean;
host?: string;
open?: boolean;
port?: number;
proxy?: any;
public?: string;
}

export interface TemplateData {
IMPORT_LIST: string[];
USER_CONFIG: string;
}
25 changes: 25 additions & 0 deletions src/config/parse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import fs from "fs";
import { WebpackConfig } from "./webpack";
import { VueCliConfig } from "./vuecli";

export async function parseWebpackConfig(
configPath: string
): Promise<WebpackConfig> {
let webpackConfig: WebpackConfig = {};
await import(configPath).then((config) => {
webpackConfig = config;
});
return webpackConfig;
}

export async function parseVueCliConfig(
configPath: string
): Promise<VueCliConfig> {
let vueCliConfig: VueCliConfig = {};
if (fs.existsSync(configPath)) {
await import(configPath).then((config) => {
vueCliConfig = config;
});
}
return vueCliConfig;
}
25 changes: 25 additions & 0 deletions src/config/vite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { UserConfig, ResolveOptions } from "vite";

export class RawValue {
value: string;
constructor(val: string) {
this.value = val;
}
public toString(): string {
return this.value;
}
}

export declare interface ViteConfig
extends Omit<UserConfig, "plugins" | "resolve"> {
plugins?: RawValue[];

resolve?: ResolveOptions & {
alias?: Alias[];
};
}

export declare interface Alias {
find: RawValue | string;
replacement: RawValue | string;
}
29 changes: 29 additions & 0 deletions src/config/vuecli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Config, DevServer } from "./config";

export interface VueCliConfig extends Config {
baseUrl?: string;
publicPath?: string;
outputDir?: string;
assetsDir?: string;
indexPath?: string;
filenameHashing?: boolean;
pages?: Record<string, any>;
lintOnSave?: string;
runtimeCompiler?: boolean;
transpileDependencies?: [];
productionSourceMap?: boolean;
crossorigin?: string;
integrity?: boolean;
configureWebpack?: any;
// eslint-disable-next-line @typescript-eslint/ban-types
chainWebpack?: Function;
css?: {
sourceMap?: boolean;
loaderOptions?: Record<string, any>;
extract?: any;
};
devServer?: DevServer;
parallel?: boolean;
pwa?: Record<string, never>;
pluginOptions?: Record<string, any>;
}
33 changes: 33 additions & 0 deletions src/config/webpack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Config, DevServer } from "./config";

export interface WebpackConfig extends Config {
mode?: string;
entry?: string;
output?: Output;
module?: Module;
resolve?: Resolve;
devServer?: DevServer;
}

export interface Output {
path?: string;
filename?: string;
publicPath?: string;
}

export interface Module {
rules: Rule[];
}

export interface Rule {
test: RegExp;
include?: [];
exclude?: [];
loader: string;
}

export interface Resolve {
modules: [];
extensions?: [];
alias: Record<string, never>;
}
7 changes: 7 additions & 0 deletions src/constants/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const DEFAULT_VUE_VERSION = 2;
export const VUE_COMPILER_SFC_VERSION = "^3.0.5";
export const VITE_VERSION = "^2.1.5";
export const VITE_PLUGIN_VUE_VERSION = "^1.2.1";
export const VITE_PLUGIN_VUE_TWO_VERSION = "^1.5.1";
export const VITE_PLUGIN_ENV_COMPATIBLE = "^1.0.0";
export const SASS_VERSION = "^1.34.0";
41 changes: 41 additions & 0 deletions src/generate/geneIndexHtml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import fs from 'fs'
import path from 'path'
import { readSync, writeSync } from '../utils/file'

export function genIndexHtml(root: string): void {
const filePath = path.resolve(root, '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)
const injectedContent = injectHtml(htmlContent, entries)
writeSync(filePath, injectedContent)
}

export function injectHtml(source: string, entries: string[]): string {
const bodyRegex = /<body[^>]*>((.|[\n\r])*)<\/body>/im
let body = ' <body>\n'
body += ' <div id="app"></div>\n'
for (const entry of entries) {
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')
if (fs.existsSync(mainFile)) {
entries.push('/src/main.ts')
} else {
entries.push('/src/main.js')
}
// TODO: vue-cli pages config
return entries
}

40 changes: 40 additions & 0 deletions src/generate/genePackageJson.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { readSync, writeSync } from '../utils/file'
import { getVueVersion } from '../utils/version'
import path from 'path'
import * as constants from '../constants/constants'

// TODO: compatible with vue2 and vue3
export function genePackageJson(packageJsonPath: string): void {
const rootDir = path.dirname(packageJsonPath)
const source = readSync(packageJsonPath)
if (source === '') {
console.log(`read package.json error, path: ${rootDir}`)
}

const packageJson = JSON.parse(source)
if (packageJson === '') {
console.log(`parse json error, path: ${rootDir}`)
}

const vueVersion = getVueVersion(rootDir)
if (vueVersion === 3) {
packageJson.devDependencies['@vue/compiler-sfc'] = constants.VUE_COMPILER_SFC_VERSION
packageJson.devDependencies['@vitejs/plugin-vue'] = constants.VITE_PLUGIN_VUE_VERSION
} else if (vueVersion === 2) {
packageJson.devDependencies['vite-plugin-vue2'] = constants.VITE_PLUGIN_VUE_TWO_VERSION
}

packageJson.devDependencies['vite-plugin-env-compatible'] = constants.VITE_PLUGIN_ENV_COMPATIBLE
packageJson.devDependencies['vite'] = constants.VITE_VERSION

// sass support
if (packageJson.devDependencies['node-sass'] && !packageJson.devDependencies['sass']) {
packageJson.devDependencies['sass'] = constants.SASS_VERSION
}

// add vite dev script
packageJson.scripts['serve-vite'] = 'vite'
packageJson.scripts['build-vite'] = 'build vite'

writeSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
}
Loading

0 comments on commit 2d130b6

Please sign in to comment.