From 3bf3a2b68041b53cd047c6069643794a1a69f5e7 Mon Sep 17 00:00:00 2001 From: Leah Date: Fri, 15 Mar 2019 15:16:24 +0100 Subject: [PATCH] Typescript support with babel (#747) --- packages/cli/lib/lib/babel-config.js | 6 ++ .../lib/lib/webpack/webpack-base-config.js | 39 +++++++++--- packages/cli/lib/resources/tsconfig.json | 12 ++++ packages/cli/package.json | 4 ++ yarn.lock | 59 +++++++++++++++++++ 5 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 packages/cli/lib/resources/tsconfig.json diff --git a/packages/cli/lib/lib/babel-config.js b/packages/cli/lib/lib/babel-config.js index c7b4b437a..6382b0e8b 100644 --- a/packages/cli/lib/lib/babel-config.js +++ b/packages/cli/lib/lib/babel-config.js @@ -3,6 +3,12 @@ module.exports = function(env, options = {}) { return { presets: [ + [ + require.resolve('@babel/preset-typescript'), + { + jsxPragma: 'h', + }, + ], [ require.resolve('@babel/preset-env'), { diff --git a/packages/cli/lib/lib/webpack/webpack-base-config.js b/packages/cli/lib/lib/webpack/webpack-base-config.js index ae374314f..0b6c82ec0 100644 --- a/packages/cli/lib/lib/webpack/webpack-base-config.js +++ b/packages/cli/lib/lib/webpack/webpack-base-config.js @@ -9,6 +9,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries'); const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const ReplacePlugin = require('webpack-plugin-replace'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const createBabelConfig = require('../babel-config'); function readJson(file) { @@ -46,6 +47,16 @@ function findAllNodeModules(startDir) { } } +function resolveTsconfig(cwd, isProd, fallback) { + if (existsSync(resolve(cwd, `tsconfig.${isProd ? 'prod' : 'dev'}.json`))) { + return resolve(cwd, `tsconfig.${isProd ? 'prod' : 'dev'}.json`); + } else if (existsSync(resolve(cwd, 'tsconfig.json'))) { + return resolve(cwd, 'tsconfig.json'); + } else { + return fallback; + } +} + module.exports = function(env) { const { cwd, isProd, isWatch, src, source } = env; @@ -67,6 +78,18 @@ module.exports = function(env) { compat = 'preact/compat'; } catch (e) {} + let babelConfig = Object.assign( + { babelrc: false }, + createBabelConfig(env, { browsers }), + babelrc // intentionally overwrite our settings + ); + + let tsconfig = resolveTsconfig( + cwd, + isProd, + resolve(__dirname, '../../resources/tsconfig.json') + ); + return { context: src, @@ -87,7 +110,7 @@ module.exports = function(env) { ], alias: { style: source('style'), - 'preact-cli-entrypoint': source('index.js'), + 'preact-cli-entrypoint': source('index'), // preact-compat aliases for supporting React dependencies: react: compat, 'react-dom': compat, @@ -110,15 +133,11 @@ module.exports = function(env) { { // ES2015 enforce: 'pre', - test: /\.m?jsx?$/, + test: /\.m?[jt]sx?$/, resolve: { mainFields: ['module', 'jsnext:main', 'browser', 'main'] }, type: 'javascript/auto', loader: 'babel-loader', - options: Object.assign( - { babelrc: false }, - createBabelConfig(env, { browsers }), - babelrc // intentionally overwrite our settings - ), + options: babelConfig, }, { // LESS @@ -260,6 +279,12 @@ module.exports = function(env) { clear: true, }), new SizePlugin(), + new ForkTsCheckerWebpackPlugin({ + checkSyntacticErrors: true, + async: !isProd, + tsconfig: tsconfig, + silent: !isWatch, + }), ].concat( isProd ? [ diff --git a/packages/cli/lib/resources/tsconfig.json b/packages/cli/lib/resources/tsconfig.json new file mode 100644 index 000000000..7a9f5c543 --- /dev/null +++ b/packages/cli/lib/resources/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "esModuleInterop": true, + + "module": "esnext", + "target": "esnext", + + "noEmit": true + }, + "exclude": ["*"] +} diff --git a/packages/cli/package.json b/packages/cli/package.json index d078d2824..175813759 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -75,6 +75,7 @@ "@babel/plugin-transform-react-constant-elements": "^7.2.0", "@babel/plugin-transform-react-jsx": "^7.3.0", "@babel/preset-env": "^7.3.4", + "@babel/preset-typescript": "^7.3.3", "@preact/async-loader": "^3.0.0-next.16", "autoprefixer": "^9.4.10", "babel-esm-plugin": "^0.4.0", @@ -90,6 +91,7 @@ "esm": "^3.2.17", "fast-async": "^6.3.7", "file-loader": "^3.0.1", + "fork-ts-checker-webpack-plugin": "^0.5.2", "get-port": "^4.2.0", "gittar": "^0.1.0", "glob": "^7.1.3", @@ -117,6 +119,8 @@ "stack-trace": "0.0.10", "style-loader": "^0.23.1", "sw-precache-webpack-plugin": "^0.11.2", + "terser-webpack-plugin": "^1.1.0", + "typescript": "^3.3.3333", "update-notifier": "^2.5.0", "url-loader": "^1.0.1", "validate-npm-package-name": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 1c198d5c8..f54fdc3c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -446,6 +446,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-typescript@^7.2.0": + version "7.3.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz#a7cc3f66119a9f7ebe2de5383cce193473d65991" + integrity sha512-dGwbSMA1YhVS8+31CnPR7LB4pcbrzcV99wQzby4uAfrkZPYZlQ7ImwdpzLqi6Z6IL02b8IAL379CaMwo0x5Lag== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-arrow-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" @@ -692,6 +699,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-typescript@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.3.2.tgz#59a7227163e55738842f043d9e5bd7c040447d96" + integrity sha512-Pvco0x0ZSCnexJnshMfaibQ5hnK8aUHSvjCQhC1JR8eeg+iBwt0AtCO7gWxJ358zZevuf9wPSO5rv+WJcbHPXQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-typescript" "^7.2.0" + "@babel/plugin-transform-unicode-regex@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b" @@ -750,6 +765,14 @@ js-levenshtein "^1.1.3" semver "^5.3.0" +"@babel/preset-typescript@^7.3.3": + version "7.3.3" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.3.3.tgz#88669911053fa16b2b276ea2ede2ca603b3f307a" + integrity sha512-mzMVuIP4lqtn4du2ynEfdO0+RYcslwrZiJHXu4MGaC1ctJiW2fyaeDrtjJGs7R/KebZ1sgowcIoWf4uRpEfKEg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-typescript" "^7.3.2" + "@babel/runtime@7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c" @@ -2519,6 +2542,15 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + babel-eslint@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" @@ -5355,6 +5387,18 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +fork-ts-checker-webpack-plugin@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-0.5.2.tgz#a73b3630bd0a69409a6e4824e54c03a62fe82d8f" + integrity sha512-a5IG+xXyKnpruI0CP/anyRLAoxWtp3lzdG6flxicANnoSzz64b12dJ7ASAVRrI2OaWwZR2JyBaMHFQqInhWhIw== + dependencies: + babel-code-frame "^6.22.0" + chalk "^2.4.1" + chokidar "^2.0.4" + micromatch "^3.1.10" + minimatch "^3.0.4" + tapable "^1.0.0" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -7187,6 +7231,11 @@ js-string-escape@^1.0.1: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.9.0: version "3.12.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" @@ -12159,6 +12208,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript@^3.3.3333: + version "3.3.3333" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.3333.tgz#171b2c5af66c59e9431199117a3bcadc66fdcfd6" + integrity sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw== + uglify-es@^3.3.9: version "3.3.9" resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" @@ -12195,6 +12249,11 @@ unfetch@^4.0.0: resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.0.1.tgz#8750c4c7497ade75d40387d7dbc4ba024416b8f6" integrity sha512-HzDM9NgldcRvHVDb/O9vKoUszVij30Yw5ePjOZJig8nF/YisG7QN/9CBXZ8dsHLouXMeLZ82r+Jod9M2wFkEbQ== +unfetch@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.1.0.tgz#6ec2dd0de887e58a4dee83a050ded80ffc4137db" + integrity sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg== + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"