Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.

Commit 240c0f7

Browse files
Jack-Worksznck
authored andcommitted
feat: typescript support (#109)
* Add support for Typescript * Add inject support for `export defaults Var` when Var refers to a class, function or Object * Fix eslint * fix: normalize script language names * Add test for Typescript support * Fix test for typescript
1 parent 5ba1684 commit 240c0f7

17 files changed

+160
-47
lines changed

config/build.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ rollup.rollup({
4848
'stylus',
4949
'vue-template-es2015-compiler',
5050
'vue-template-validator',
51+
'typescript'
5152
].indexOf(id) > -1
5253
}
5354
})

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"posthtml": "^0.9.2",
5050
"posthtml-attrs-parser": "^0.1.1",
5151
"rollup-pluginutils": "^2.0.1",
52+
"typescript": "^2.4.1",
5253
"vue-template-compiler": "*",
5354
"vue-template-es2015-compiler": "^1.5.0",
5455
"vue-template-validator": "^1.1.5"

src/injections.js

Lines changed: 45 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/options.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { templateJs, moduleJs, scopeJs, renderJs } from './injections'
2-
import { coffee } from './script/index'
2+
import { coffee, typescript } from './script/index'
33

44
export default {
55
// Style compilation options.
@@ -73,28 +73,32 @@ export default {
7373
inject: {
7474
template: {
7575
js: templateJs,
76-
babel: templateJs
76+
ts: templateJs,
77+
coffee: templateJs
7778
},
7879

7980
render: {
8081
js: renderJs,
81-
babel: renderJs
82+
ts: renderJs,
83+
coffee: renderJs
8284
},
8385

8486
module: {
8587
js: moduleJs,
86-
babel: moduleJs
88+
ts: moduleJs,
89+
coffee: moduleJs
8790
},
8891

8992
scoped: {
9093
js: scopeJs,
91-
babel: scopeJs
94+
ts: scopeJs,
95+
coffee: scopeJs
9296
}
9397
},
9498

9599
// script languages.
96100
script: {
97101
coffee,
98-
coffeescript: coffee
102+
ts: typescript
99103
}
100104
}

src/script/coffee.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ export default function (script) {
44
return new Promise((resolve, reject) => {
55
coffee.compile(script.code, { bare: true }, (status, output) => {
66
if (status === 0) {
7-
script.code = output
7+
script.code = output.replace(/^\/\/ Generated by CoffeeScript [\d]+.[\d]+.[\d]+/i, '')
8+
console.log(script.code)
89

910
resolve(script)
1011
} else {

src/script/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { default as coffee } from './coffee'
2+
export { default as typescript } from './typescript'

src/script/typescript.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import * as Typescript from 'typescript'
2+
import debug from '../debug'
3+
export default async function (script, id, content, options, nodes) {
4+
debug(`Typescript: Compiling ${id}`)
5+
options.typescript = options.typescript || {}
6+
const config = Object.assign({}, options.typescript, { fileName: id })
7+
config.compilerOptions = Object.assign({}, options.typescript.compilerOptions, {
8+
experimentalDecorators: true,
9+
module: Typescript.ModuleKind.ES2015,
10+
moduleResolution: Typescript.ModuleResolutionKind.NodeJs
11+
})
12+
script.code = (await Typescript.transpileModule(script.code, config)).outputText
13+
return script
14+
}

src/vueTransform.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ function getNodeAttrs (node) {
2929
*/
3030
function padContent (content) {
3131
return content
32-
.split(/\r?\n/g)
33-
.map(() => '')
34-
.join('\n')
32+
.split(/\r?\n/g)
33+
.map(() => '')
34+
.join('\n')
3535
}
3636

3737
function validateTemplate (code, content, id) {
@@ -54,9 +54,9 @@ async function processTemplate (source, id, content, options, nodes, modules) {
5454
const extras = { modules, id, lang: source.attrs.lang }
5555
const code = deIndent(source.code)
5656
const template = await (
57-
options.disableCssModuleStaticReplacement !== true
58-
? templateProcessor(code, extras, options)
59-
: code
57+
options.disableCssModuleStaticReplacement !== true
58+
? templateProcessor(code, extras, options)
59+
: code
6060
)
6161

6262
if (!options.compileTemplate) {
@@ -66,11 +66,28 @@ async function processTemplate (source, id, content, options, nodes, modules) {
6666
return htmlMinifier.minify(template, options.htmlMinifier)
6767
}
6868

69+
/* eslint-disable complexity */
70+
function normalizeLang (any) {
71+
switch (any) {
72+
case 'coffee':
73+
case 'coffeescript':
74+
case 'coffee-script':
75+
return 'coffee'
76+
case 'ts':
77+
case 'typescript':
78+
case 'type-script':
79+
return 'ts'
80+
default:
81+
return 'js'
82+
}
83+
}
84+
/* eslint-enable complexity */
85+
6986
async function processScript (source, id, content, options, nodes, modules, scoped) {
7087
const template = await processTemplate(nodes.template[0], id, content, options, nodes, modules)
7188

7289
debug(`Process script: ${id}`)
73-
const lang = 'js'
90+
const lang = normalizeLang(source.attrs.lang)
7491

7592
if (source.attrs.lang && ['js', 'babel'].indexOf(source.attrs.lang) < 0) {
7693
if (!(source.attrs.lang in options.script)) {
@@ -123,7 +140,7 @@ async function processStyle (styles, id, content, options) {
123140
const style = styles[i]
124141

125142
const code = deIndent(
126-
padContent(content.slice(0, content.indexOf(style.code))) + style.code
143+
padContent(content.slice(0, content.indexOf(style.code))) + style.code
127144
)
128145

129146
const map = (new MagicString(code)).generateMap({ hires: true })
@@ -199,7 +216,6 @@ const hasScoped = function (styles) {
199216
return scoped || style.scoped
200217
}, false)
201218
}
202-
203219
export default async function vueTransform (code, id, options) {
204220
const nodes = parseTemplate(code)
205221
const css = await processStyle(nodes.style, id, code, options, nodes)

test/expects/coffee.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
// Generated by CoffeeScript 1.12.4
21
var component;
32

4-
component = { template: "<h1 :id=\"id\" @click=\"hi\">hello</h1><input type=\"text\">",
3+
component = { template: "<h1 :id=\"id\" @click=\"hi\">hello</h1>",
54
data: function() {
65
return [2, 4, 6, 8];
76
}

test/expects/typescript-export-obj.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var app = {
2+
};
3+
4+
var __$app = Object.assign(app, { template: "<h1 :id=\"id\" @click=\"hi\">hello</h1><input type=\"text\">",});
5+
__$app.prototype = app.prototype;
6+
7+
export default __$app;

test/expects/typescript.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
var component = { template: "<h1 :id=\"id\" @click=\"hi\">hello</h1><input type=\"text\">",
2+
data: function () { return ({
3+
hello: 'world!'
4+
}); },
5+
methods: {
6+
hello: function () {
7+
return this.hello;
8+
}
9+
}
10+
};
11+
12+
export default component;

test/fixtures/app.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export default {
2+
}

test/fixtures/coffee.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<template>
22
<h1 :id="id" @click="hi">hello</h1>
3-
<input type="text">
43
</template>
54

65
<script lang="coffee">
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<template>
2+
<h1 :id="id" @click="hi">
3+
hello</h1>
4+
<input type="text">
5+
</template>
6+
7+
<script lang="ts">
8+
import app from './app.ts'
9+
export default app
10+
</script>

test/fixtures/typescript.vue

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<template>
2+
<h1 :id="id" @click="hi">
3+
hello</h1>
4+
<input type="text">
5+
</template>
6+
7+
<script lang="ts">
8+
import Vue from 'vue'
9+
interface Data {
10+
hello: string
11+
}
12+
const component = {
13+
data: () => ({
14+
hello: 'world!'
15+
}),
16+
methods: {
17+
hello() {
18+
return this.hello
19+
}
20+
}
21+
} as Vue.ComponentOptions<Data & Vue>
22+
23+
export default component
24+
</script>

test/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function test(name) {
7575
describe('rollup-plugin-vue', function () {
7676
fs.readdirSync(path.resolve(__dirname, 'fixtures'))
7777
.forEach(function (file) {
78-
test(file.substr(0, file.length - 4))
78+
file.endsWith('.vue') && test(file.substr(0, file.length - 4))
7979
})
8080
})
8181

yarn.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3243,6 +3243,10 @@ typedarray@^0.0.6:
32433243
version "0.0.6"
32443244
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
32453245

3246+
typescript@^2.4.1:
3247+
version "2.4.1"
3248+
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.1.tgz#c3ccb16ddaa0b2314de031e7e6fee89e5ba346bc"
3249+
32463250
uglify-js@2.7.x, uglify-js@^2.6, uglify-js@^2.6.1, uglify-js@^2.7.5:
32473251
version "2.7.5"
32483252
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8"

0 commit comments

Comments
 (0)