Skip to content

Commit

Permalink
fix: support custom babel config for ts files, closes #78
Browse files Browse the repository at this point in the history
  • Loading branch information
egoist committed Oct 9, 2020
1 parent 2223d2f commit e72e70c
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 97 deletions.
10 changes: 4 additions & 6 deletions src/compileScript.ts
Expand Up @@ -10,14 +10,12 @@ export const compileScript = async (

const code = script.content.replace(/^\/\/$/gm, '')

if (script.lang === 'ts' || script.lang === 'typescript') {
script.content = await import('./script-compilers/ts').then(
async ({ compile }) => compile(code, ctx)
)
} else if (
if (
!script.lang ||
script.lang === 'esnext' ||
script.lang === 'babel'
script.lang === 'babel' ||
script.lang === 'ts' ||
script.lang === 'typescript'
) {
script.content = await import('./script-compilers/babel').then(
async ({ compile }) => compile(code, ctx)
Expand Down
119 changes: 61 additions & 58 deletions src/index.ts
Expand Up @@ -4,7 +4,7 @@ import fs from 'fs-extra'
import JoyCon from 'joycon'
import isBinaryPath from 'is-binary-path'
import createDebug from 'debug'
import { replaceContants, cssExtensionsRe } from './utils'
import { replaceContants, cssExtensionsRe, jsExtensionsRe } from './utils'

const debug = createDebug('vue-compile:cli')

Expand Down Expand Up @@ -58,16 +58,19 @@ class VueCompile extends EventEmitter {
debug(`Using config file: ${configPath}`)
}

options = { ...options, ...config}
options = { ...options, ...config }
}

this.options = this.normalizeOptions(options)
this.isInputFile = fs.statSync(this.options.input).isFile()
}

normalizeOptions(options: InputOptions): NormalizedOptions {
return { ...options, input: path.resolve(options.input),
output: path.resolve(options.output)}
return {
...options,
input: path.resolve(options.input),
output: path.resolve(options.output)
}
}

async normalize(): Promise<void> {
Expand Down Expand Up @@ -124,40 +127,39 @@ class VueCompile extends EventEmitter {
}
)

const script = await import('./compileScript').then(async ({ compileScript }) =>
compileScript(sfcDescriptor.script, ctx)
const script = await import('./compileScript').then(
async ({ compileScript }) => compileScript(sfcDescriptor.script, ctx)
)
const template = await import('./compileTemplate').then(
async ({ compileTemplate }) => compileTemplate(sfcDescriptor.template)
)
const styles = await import('./compileStyles').then(async ({ compileStyles }) =>
compileStyles(sfcDescriptor.styles, ctx)
const styles = await import('./compileStyles').then(
async ({ compileStyles }) => compileStyles(sfcDescriptor.styles, ctx)
)

await import('./writeSFC').then(async ({writeSFC}) => writeSFC(
{
script,
styles,
template,
customBlocks: sfcDescriptor.customBlocks
},
outFile
))
await import('./writeSFC').then(async ({ writeSFC }) =>
writeSFC(
{
script,
styles,
template,
customBlocks: sfcDescriptor.customBlocks
},
outFile
)
)

this.emit('normalized', input, outFile)
}

async normalizeDir(input: string, outDir: string): Promise<void> {
const include = [...(this.options.include || [])]
const exclude = [...(this.options.exclude || [])]
const include = [...(this.options.include ?? [])]
const exclude = [...(this.options.exclude ?? [])]
const { default: glob } = await import('fast-glob')
const files = await glob(
include.length > 0 ? include : ['**/*'],
{
cwd: input,
ignore: ['**/node_modules/**'].concat(exclude)
}
)
const files = await glob(include.length > 0 ? include : ['**/*'], {
cwd: input,
ignore: ['**/node_modules/**'].concat(exclude)
})
await Promise.all(
files.map(async (file: string) => {
return this.normalizeFile(
Expand All @@ -184,51 +186,51 @@ class VueCompile extends EventEmitter {
): Promise<void> {
let output

if (filename.endsWith('.js')) {
output = await import('./script-compilers/babel').then(async ({ compile }) => {
return compile(source, {
filename,
babelrc,
modern
})
})
} else if (filename.endsWith('.ts')) {
output = await import('./script-compilers/ts').then(async ({ compile }) => {
return compile(source, {
filename,
babelrc,
modern
})
})
outFile = outFile.replace(/\.ts$/, '.js')
if (jsExtensionsRe.test(filename)) {
output = await import('./script-compilers/babel').then(
async ({ compile }) => {
return compile(source, {
filename,
babelrc,
modern
})
}
)
} else if (filename.endsWith('.css')) {
output = await import('./style-compilers/postcss').then(async ({ compile }) => {
return compile(source, { filename })
})
output = await import('./style-compilers/postcss').then(
async ({ compile }) => {
return compile(source, { filename })
}
)
} else if (/\.s[ac]ss$/.test(filename)) {
const basename = path.basename(filename)
if (basename.startsWith('_')) {
// Ignore sass partial files
return
}

output = await import('./style-compilers/sass').then(async ({ compile }) => {
return compile(source, {
filename,
indentedSyntax: filename.endsWith(".sass")
})
})
output = await import('./style-compilers/sass').then(
async ({ compile }) => {
return compile(source, {
filename,
indentedSyntax: filename.endsWith('.sass')
})
}
)
} else if (/\.styl(us)?/.test(filename)) {
output = await import('./style-compilers/stylus').then(async ({ compile }) => {
return compile(source, {
filename
})
})
output = await import('./style-compilers/stylus').then(
async ({ compile }) => {
return compile(source, {
filename
})
}
)
} else {
output = source
}

outFile = outFile.replace(cssExtensionsRe, '.css')
outFile = outFile.replace(jsExtensionsRe, '.js')

await fs.outputFile(outFile, output, 'utf8')

Expand All @@ -245,4 +247,5 @@ class VueCompile extends EventEmitter {
}
}

export const createCompiler = (opts: InputOptions): VueCompile => new VueCompile(opts)
export const createCompiler = (opts: InputOptions): VueCompile =>
new VueCompile(opts)
15 changes: 5 additions & 10 deletions src/script-compilers/babel.ts
Expand Up @@ -2,27 +2,22 @@ import path from 'path'
import createDebug from 'debug'
import { TransformOptions } from '@babel/core'
import { ScriptCompilerContext } from '../types'
import { getBabelConfigFile } from '../utils'

const debug = createDebug('vue-compile:script')

const cache = new Map()

export const compile = async (
code: string,
{ filename, modern, babelrc }: ScriptCompilerContext
): Promise<string> => {
const cwd = path.dirname(filename)
const file: string | null =
babelrc === false
? null
: cache.get(cwd) ||
require('find-babel-config')(cwd).then((res: any) => res.file)

cache.set(cwd, file)
const babelConfigFile = getBabelConfigFile(cwd, babelrc)

const config: TransformOptions = {
filename,
presets: [
require.resolve('@babel/preset-typescript'),
[
require.resolve('../babel/preset'),
{
Expand All @@ -32,9 +27,9 @@ export const compile = async (
]
}

if (file) {
if (babelConfigFile) {
config.babelrc = true
debug(`Using Babel config file at ${file}`)
debug(`Using Babel config file at ${babelConfigFile}`)
} else {
config.babelrc = false
}
Expand Down
21 changes: 0 additions & 21 deletions src/script-compilers/ts.ts

This file was deleted.

29 changes: 27 additions & 2 deletions src/utils.ts
@@ -1,6 +1,7 @@
import path from 'path'

export const humanlizePath = (p: string): string => path.relative(process.cwd(), p)
export const humanlizePath = (p: string): string =>
path.relative(process.cwd(), p)

export const notSupportedLang = (lang: string, tag: string): string => {
return `"${lang}" is not supported for <${tag}> tag currently, wanna contribute this feature?`
Expand All @@ -10,7 +11,10 @@ function escapeRe(str: string): string {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&')
}

export const replaceContants = (content: string, constants?: {[k:string]:any}): string => {
export const replaceContants = (
content: string,
constants?: { [k: string]: any }
): string => {
if (!constants) return content

const RE = new RegExp(
Expand All @@ -27,3 +31,24 @@ export const replaceContants = (content: string, constants?: {[k:string]:any}):
}

export const cssExtensionsRe = /\.(css|s[ac]ss|styl(us)?)$/

export const jsExtensionsRe = /\.[jt]sx?$/

const babelConfigCache: Map<string, string | null> = new Map()

/**
* Find babel config file in cwd
* @param cwd
* @param babelrc Whether to load babel config file
*/
export const getBabelConfigFile = (cwd: string, babelrc?: boolean) => {
const file: string | null =
babelrc === false
? null
: babelConfigCache.get(cwd) ??
require('find-babel-config')(cwd).then((res: any) => res.file)

babelConfigCache.set(cwd, file)

return file
}

0 comments on commit e72e70c

Please sign in to comment.