Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rollup & multitarget support #11

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dist/
tests/fixture/
demo-dist/
5 changes: 4 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ module.exports = {
camelcase: 'off',
'@typescript-eslint/quotes': ['error', 'single'],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/member-delimiter-style': ['error', { multiline: { delimiter: 'comma', requireLast: false }, singleline: { delimiter: 'comma', requireLast: false }, overrides: { interface: { multiline: { delimiter: 'none' } } } }]
'@typescript-eslint/member-delimiter-style': ['error', { multiline: { delimiter: 'comma', requireLast: false }, singleline: { delimiter: 'comma', requireLast: false }, overrides: { interface: { multiline: { delimiter: 'none' } } } }],
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off'
},
parserOptions: {
sourceType: 'module',
Expand Down
2 changes: 1 addition & 1 deletion bin/vc2c
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/usr/bin/env node
require('../dist/lib/cli.js')
require('../dist/cli.js')
2 changes: 1 addition & 1 deletion demo/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as monaco from 'monaco-editor/esm/vs/editor/editor.main.js'
import { convert } from '../src/index'
import { convert } from '../dist/index.browser'

const defaultCode = `import Vue from 'vue'
import { Prop, Component, Ref, Model, Provide, Inject } from 'vue-property-decorator'
Expand Down
62 changes: 36 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
"version": "1.4.0",
"author": "<yoyo930021>yoyo930021@gmail.com",
"license": "MIT",
"main": "dist/lib/index.js",
"typings": "dist/types/index.d.ts",
"main": "./dist/index.js",
"browser": "./dist/index.browser.mjs",
"module": "./dist/index.mjs",
"typings": "./dist/types/src/index.d.ts",
"bin": {
"vc2c": "./bin/vc2c"
},
Expand All @@ -18,41 +20,49 @@
"LICENSE"
],
"devDependencies": {
"@semantic-release/git": "^7.0.18",
"@types/inquirer": "^6.5.0",
"@types/jest": "^24.0.24",
"@types/node": "^12.12.21",
"@types/prettier": "^1.19.0",
"@typescript-eslint/eslint-plugin": "^2.12.0",
"@typescript-eslint/parser": "^2.12.0",
"codecov": "^3.6.5",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-node": "^10.0.0",
"@rollup/plugin-commonjs": "14.0.0",
"@rollup/plugin-json": "4.1.0",
"@rollup/plugin-node-resolve": "8.4.0",
"@rollup/plugin-replace": "2.3.3",
"@semantic-release/git": "^9.0.0",
"@types/inquirer": "^7.3.0",
"@types/jest": "^26.0.7",
"@types/node": "14.0.27",
"@types/prettier": "^2.0.2",
"codecov": "^3.7.2",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"jest": "^24.9.0",
"monaco-editor": "^0.18.1",
"jest": "^26.1.0",
"monaco-editor": "^0.20.0",
"parcel-bundler": "^1.12.4",
"prettier": "^1.19.1",
"semantic-release": "^15.13.31",
"ts-jest": "^24.2.0",
"typescript": "3.7.3",
"rollup": "2.23.0",
"rollup-plugin-inject-process-env": "1.3.0",
"rollup-plugin-typescript2": "0.27.1",
"semantic-release": "^17.1.1",
"ts-jest": "^26.1.4",
"vue": "^2.6.11"
},
"scripts": {
"lint": "eslint . --ext .ts",
"build": "tsc -p tsconfig.compile.json",
"build": "rollup -c",
"test": "yarn build && jest --config jest.config.js",
"demo:prepare": "parcel build node_modules/monaco-editor/esm/vs/editor/editor.worker.js --no-source-maps -d demo-dist/ && parcel build node_modules/monaco-editor/esm/vs/language/typescript/ts.worker.js --no-source-maps -d demo-dist/",
"demo:build": "yarn demo:prepare && parcel build demo/index.html --no-source-maps -d demo-dist/ --public-url ./"
"demo:build": "yarn build && yarn demo:prepare && parcel build demo/index.html --no-source-maps -d demo-dist/ --public-url ./"
},
"dependencies": {
"commander": "^4.0.1",
"eslint": "^6.7.2",
"inquirer": "^7.0.1",
"prettier-eslint": "^9.0.1",
"ts-node": "^8.5.4",
"@typescript-eslint/eslint-plugin": "^3.7.1",
"@typescript-eslint/parser": "^3.7.1",
"commander": "^6.0.0",
"core-js": "3.6.5",
"eslint": "^7.5.0",
"inquirer": "^7.3.3",
"prettier": "^2.0.5",
"prettier-eslint": "^11.0.0",
"ts-node": "^8.10.2",
"typescript": "3.9.7",
"vue-template-compiler": "^2.6.11"
},
"repository": {
Expand Down
46 changes: 46 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import replace from '@rollup/plugin-replace'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add replace({ 'process.env.BROWSER': 'false' }) for outputs without browser.

import typescript from 'rollup-plugin-typescript2'

const pluginTypeScript = typescript({
useTsconfigDeclarationDir: true,
tsconfig: 'tsconfig.compile.json'
})
const pluginJson = json()
const pluginCommonJs = commonjs()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pluginCommonJs is needed when any output.
Because it is converting CommonJS modules to ES6 for dependencies


export default [
{
input: 'src/index.ts',
output: {
file: 'dist/index.js',
format: 'cjs'
},
plugins: [pluginJson, pluginCommonJs, pluginTypeScript]
},
{
input: 'src/index.ts',
output: {
file: 'dist/index.mjs',
format: 'es'
},
plugins: [pluginJson, pluginTypeScript]
},
{
input: 'src/index.ts',
output: {
file: 'dist/index.browser.mjs',
format: 'es'
},
plugins: [replace({ 'process.env.BROWSER': 'true' }), pluginJson, pluginTypeScript]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can replace process.env.BROWSER to __BROWSER__.

},
{
input: 'src/cli.ts',
output: {
file: 'dist/cli.js',
format: 'cjs'
},
plugins: [pluginJson, pluginCommonJs, pluginTypeScript]
}
]
6 changes: 4 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import program from 'commander'
import { convertFile } from './index.js'
import inquirer from 'inquirer'
import { version } from '../package.json'
import { writeFileInfo } from './file'

const { convertFile } = require('./index.js')

function camelize (str: string) {
return str.replace(/-(\w)/g, (_, c) => c ? c.toUpperCase() : '')
}
Expand All @@ -21,7 +23,7 @@ function getCmdOptions (cmd: any) {
}

program
.version(require('../../package.json').version)
.version(version)
Copy link
Owner

@yoyo930021 yoyo930021 Aug 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This version is wrong on release.
Because bundling is before upgrading package.json version.

.usage('<command> [options]')

program
Expand Down
6 changes: 3 additions & 3 deletions src/convert.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as ts from 'typescript'
import ts from 'typescript'
import { getDecoratorNames, getDefaultExportNode } from './utils'
import { runPlugins } from './plugins'
import { Vc2cOptions } from './options'
Expand All @@ -10,7 +10,7 @@ const vueClassModules = [
]

export function convertAST (sourceFile: ts.SourceFile, options: Vc2cOptions, program: ts.Program) {
const tsModule = options.typesciprt
const tsModule = options.typescript

log('check vue class libaray')
const vueClassModuleImportStatement = sourceFile.statements
Expand All @@ -27,7 +27,7 @@ export function convertAST (sourceFile: ts.SourceFile, options: Vc2cOptions, pro
}

log('check default export class')
const defaultExportNode = getDefaultExportNode(options.typesciprt, sourceFile)
const defaultExportNode = getDefaultExportNode(options.typescript, sourceFile)
if (!defaultExportNode) {
throw new Error('no default export class')
}
Expand Down
79 changes: 46 additions & 33 deletions src/file.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,78 @@
import path from 'path'
import fs from 'fs'
import { isVueFile, parseVueFile } from './utils'
import { Vc2cOptions } from './options'
import { log } from './debug'
import { Vc2cOptions } from './options'
import { isVueFile, parseVueFile } from './utils'
import { isAbsolute, resolve } from 'path'
import { existsSync, readFileSync, writeFileSync } from 'fs'

export enum FileKind {
VUE,
TS
}

type FileInfo = {
fsPath: string,
kind: FileKind,
content: string
} | {
fsPath: string,
kind: FileKind,
fileContent: string,
start: number,
end: number,
export type VueFileInfo = FileInfo

export interface VueSFCFileInfo extends FileInfo {
fileContent: string
start: number
end: number
}

export interface FileInfo {
fsPath: string
kind: FileKind
content: string
}

export function readVueSFCOrTsFile (filePath: string, options: Vc2cOptions): FileInfo {
const fileFsPath = (path.isAbsolute(filePath)) ? filePath : path.resolve(options.root, filePath)
const fileContent = fs.readFileSync(fileFsPath, { encoding: 'utf8' })
if (process.env.BROWSER) {
throw new Error('unsupported')
}
const fileFsPath: string = (isAbsolute(filePath)) ? filePath : resolve(options.root, filePath)
const fileContent = readFileSync(fileFsPath, { encoding: 'utf8' })
if (isVueFile(fileFsPath)) {
const scriptContent = parseVueFile(options.vueTemplateCompiler, fileContent).script
if (scriptContent) {
log(`Readed Vue file: ${fileFsPath}`)
if (scriptContent?.content != null) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does we need != null ?

log(`Read Vue file: ${fileFsPath}`)
return {
fsPath: fileFsPath,
kind: FileKind.VUE,
start: scriptContent.start,
end: scriptContent.end,
content: scriptContent.content,
start: scriptContent?.start ?? 0,
end: scriptContent?.end ?? 0,
content: scriptContent?.content ?? '',
fileContent
}
} as VueSFCFileInfo
}
throw new Error('The Vue SFC don\'t have sciprt element.')
throw new Error('The Vue SFC don\'t have script element.')
} else {
log(`Readed TS file: ${fileFsPath}`)
log(`Read TS file: ${fileFsPath}`)
return {
fsPath: fileFsPath,
kind: FileKind.TS,
content: fileContent
}
} as VueFileInfo
}
}

export function writeFileInfo (fileInfo: FileInfo, content: string) {
export function writeFileInfo (fileInfo: VueFileInfo | VueSFCFileInfo, content: string) {
if (process.env.BROWSER) {
throw new Error('unsupported')
}

const { fsPath } = fileInfo
if ('start' in fileInfo) {
log(`Write Vue file: ${fileInfo.fsPath}`)
const fileContent = `${fileInfo.fileContent.slice(0, fileInfo.start)}\n${content}${fileInfo.fileContent.slice(fileInfo.end)}`
fs.writeFileSync(fileInfo.fsPath, fileContent, { encoding: 'utf8' })
const { fileContent, start, end } = fileInfo as unknown as VueSFCFileInfo
log(`Write Vue file: ${fsPath}`)
const newFileContent = `${fileContent.slice(0, start)}\n${content}${fileContent.slice(end)}`
writeFileSync(fsPath, newFileContent, { encoding: 'utf8' })
} else {
log(`Write TS file: ${fileInfo.fsPath}`)
fs.writeFileSync(fileInfo.fsPath, content, { encoding: 'utf8' })
log(`Write TS file: ${fsPath}`)
writeFileSync(fsPath, content, { encoding: 'utf8' })
}
}

export function existsFileSync (path: string) {
return fs.existsSync(path)
export function existsFileSync (path: string): boolean {
if (process.env.BROWSER) {
throw new Error('unsupported')
}
return existsSync(path)
}
12 changes: 5 additions & 7 deletions src/format.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import { Vc2cOptions } from './options'
import path from 'path'
import { log } from './debug'
import prettier from 'prettier/standalone'
import * as prettier from 'prettier/standalone'
import prettierTypescriptParser from 'prettier/parser-typescript'
import { existsFileSync } from './file'

export function format (content: string, options: Vc2cOptions) {
export function format (content: string, options: Vc2cOptions): string {
const isNode = typeof window === 'undefined'
if (!isNode) {
if (process.env.BROWSER || !isNode) {
Comment on lines 9 to +10
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need isNode.

return prettier.format(content, {
plugins: [prettierTypescriptParser],
parser: 'typescript',
semi: false,
singleQuote: true
})
}

const eslintConfigPath = path.resolve(options.root, options.eslintConfigFile)
const prettierFormat = require('prettier-eslint')
const prettierEslintOpions = (existsFileSync(eslintConfigPath))
? {
text: content,
Expand Down Expand Up @@ -64,5 +61,6 @@ export function format (content: string, options: Vc2cOptions) {
}

log('Format result code.....')
return prettierFormat(prettierEslintOpions)
const prettierEslint = require('prettier-eslint')
return prettierEslint(prettierEslintOpions)
}
7 changes: 5 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import { setDebugMode } from './debug'
import * as BuiltInPlugins from './plugins/builtIn'

export function convert (content: string, inputOptions: InputVc2cOptions): string {
const options = mergeVc2cOptions(getDefaultVc2cOptions(inputOptions.typesciprt), inputOptions)
const options = mergeVc2cOptions(getDefaultVc2cOptions(inputOptions.typescript), inputOptions)
const { ast, program } = getSingleFileProgram(content, options)

return format(convertAST(ast, options, program), options)
}

export function convertFile (filePath: string, root: string, config: string) {
if (process.env.BROWSER) {
throw new Error('unsupported')
}
root = (typeof root === 'string')
? (
path.isAbsolute(root) ? root : path.resolve(process.cwd(), root)
Expand All @@ -27,7 +30,7 @@ export function convertFile (filePath: string, root: string, config: string) {
const inputOptions: InputVc2cOptions = existsFileSync(path.resolve(root, config))
? require(path.resolve(root, config))
: {}
const options = mergeVc2cOptions(getDefaultVc2cOptions(inputOptions.typesciprt), inputOptions)
const options = mergeVc2cOptions(getDefaultVc2cOptions(inputOptions.typescript), inputOptions)
options.root = root

if (options.debug) {
Expand Down
Loading