├── .gitignore ├── .npmignore ├── test ├── xml-valid-js │ └── input.vue ├── xml-valid-ts │ └── input.vue ├── sgml-valid-js │ └── input.vue ├── sgml-valid-ts │ └── input.vue └── index.js ├── babel.config.js ├── src ├── fileTest.js └── index.js ├── .editorconfig ├── rollup.config.js ├── LICENSE ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | node_modules/* 3 | lib/* 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | rollup.config.js 3 | .babelrc 4 | yarn.lock 5 | .editorconfig 6 | test 7 | -------------------------------------------------------------------------------- /test/xml-valid-js/input.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | -------------------------------------------------------------------------------- /test/xml-valid-ts/input.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | -------------------------------------------------------------------------------- /test/sgml-valid-js/input.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | -------------------------------------------------------------------------------- /test/sgml-valid-ts/input.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | 4 | const presets = [ 5 | [ 6 | '@babel/preset-env', 7 | { 8 | targets: { 9 | node: '10', 10 | }, 11 | }, 12 | ], 13 | ]; 14 | 15 | return { 16 | presets, 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /src/fileTest.js: -------------------------------------------------------------------------------- 1 | import * as compiler from "vue-template-compiler"; 2 | import fs from "fs"; 3 | 4 | export default filePath => { 5 | 6 | if(/\.vue$/.test(filePath)) { 7 | const { script } = compiler.parseComponent(fs.readFileSync(filePath, {encoding: "utf8"})); 8 | return !!script.lang && script.lang.toLowerCase() === "ts"; 9 | } 10 | 11 | return false; 12 | 13 | }; 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | [*.{json,cson,js,ts,vue,scss}] 12 | indent_style = space 13 | indent_size = 2 14 | charset = utf-8 15 | 16 | [*.{html,cshtml,twig}] 17 | indent_style = space 18 | indent_size = 4 19 | charset = utf-8 20 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { declare } from "@babel/helper-plugin-utils"; 2 | import fileTest from "./fileTest"; 3 | import pluginTransformTypeScript from "@babel/plugin-transform-typescript"; 4 | import presetTypeScript from "@babel/preset-typescript"; 5 | 6 | export default declare( 7 | (api, options = {}) => { 8 | 9 | api.assertVersion(7); 10 | 11 | return { 12 | "presets": [ 13 | [presetTypeScript, options] 14 | ], 15 | "overrides": [{ 16 | "test": fileTest, 17 | "plugins": [ 18 | [pluginTransformTypeScript, options] 19 | ] 20 | }] 21 | }; 22 | } 23 | ); 24 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from "rollup-plugin-babel"; 2 | import resolve from "rollup-plugin-node-resolve"; 3 | import commonjs from "rollup-plugin-commonjs"; 4 | import pkg from "./package.json"; 5 | 6 | export default { 7 | input: "./src/index.js", 8 | output: [ 9 | { 10 | file: pkg.main, 11 | format: "cjs" 12 | }, 13 | { 14 | file: pkg.module, 15 | format: "es" 16 | } 17 | ], 18 | plugins: [ 19 | babel({ 20 | include: [ "*.js", "**/*.js"], 21 | exclude: "node_modules/**" // only transpile our source code 22 | }), 23 | resolve(), 24 | commonjs() 25 | ], 26 | external: [ 27 | ...Object.keys(pkg.dependencies || {}), 28 | ...Object.keys(pkg.peerDependencies || {}), 29 | ] 30 | }; 31 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import * as path from "path"; 2 | import fileTest from "../src/fileTest"; 3 | 4 | describe("Plugin", () => { 5 | 6 | describe("File test", () => { 7 | 8 | test("parses valid XML template with JavaScript and returns false", () => { 9 | const filename = path.join(__dirname, './xml-valid-js/input.vue'); 10 | expect(fileTest(filename)).toBe(false); 11 | }); 12 | 13 | test("parses valid XML template with TypeScript and returns true", () => { 14 | const filename = path.join(__dirname, './xml-valid-ts/input.vue'); 15 | expect(fileTest(filename)).toBe(true); 16 | }); 17 | 18 | test("parses valid SGML (non-XML) template with JavaScript and returns false", () => { 19 | const filename = path.join(__dirname, './sgml-valid-js/input.vue'); 20 | expect(fileTest(filename)).toBe(false); 21 | }); 22 | 23 | test("parses valid SGML (non-XML) template with TypeScript and returns true", () => { 24 | const filename = path.join(__dirname, './sgml-valid-ts/input.vue'); 25 | expect(fileTest(filename)).toBe(true); 26 | }); 27 | 28 | }); 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2020 Paweł Gabryelewicz and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-preset-typescript-vue", 3 | "version": "1.1.1", 4 | "description": "TypeScript preset for Babel 7.x supporting Vue.js components written in TS", 5 | "main": "lib/index.js", 6 | "module": "lib/index.es.js", 7 | "scripts": { 8 | "build": "rollup -c", 9 | "test": "jest", 10 | "prepare": "npm run build", 11 | "prepublishOnly": "npm test" 12 | }, 13 | "author": "Paweł Gabryelewicz and contributors", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/pawelgabryelewicz/babel-preset-typescript-vue" 17 | }, 18 | "license": "MIT", 19 | "keywords": [ 20 | "babel-preset", 21 | "typescript", 22 | "vue" 23 | ], 24 | "dependencies": { 25 | "@babel/helper-plugin-utils": "^7.0.0", 26 | "@babel/plugin-transform-typescript": "^7.3.2", 27 | "@babel/preset-typescript": "^7.3.3", 28 | "vue-template-compiler": "^2.6.11" 29 | }, 30 | "peerDependencies": { 31 | "@babel/core": "^7.0.0-0" 32 | }, 33 | "devDependencies": { 34 | "@babel/cli": "^7.4.3", 35 | "@babel/core": "^7.4.3", 36 | "@babel/node": "^7.8.7", 37 | "@babel/preset-env": "^7.5.5", 38 | "jest": "^26.0.1", 39 | "rollup": "^1.10.0", 40 | "rollup-plugin-babel": "^4.3.2", 41 | "rollup-plugin-commonjs": "^9.3.4", 42 | "rollup-plugin-node-resolve": "^4.2.3", 43 | "vue": "^2.6.11" 44 | }, 45 | "engines": { 46 | "node": ">=8.0.0" 47 | }, 48 | "jest": { 49 | "testEnvironment": "node", 50 | "testRegex": "./test/.+\\.js$" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-preset-typescript-vue 2 | 3 | > TypeScript preset for Babel 7.x supporting Vue.js components written in TS. A drop-in replacement for [@babel/preset-typescript](https://babeljs.io/docs/en/next/babel-preset-typescript.html). 4 | 5 | ## Why? 6 | 7 | This preset was created to support TypeScript transpilation using Babel (not Microsoft TypeScript), also for [TypeScript-based Vue.js Single File Components (SFC)](https://vuejs.org/v2/guide/typescript.html), without enforced TS-to-JS transpilation for all files (which can be achieved by adding `@babel/plugin-transform-typescript` to your Babel config). 8 | 9 | Due to architectural limitations of `vue-loader` the original [@babel/preset-typescript](https://babeljs.io/docs/en/next/babel-preset-typescript.html) preset was always assuming that the `