diff --git a/packages/saber/package.json b/packages/saber/package.json
index 4ee91f05b..d84169cb2 100644
--- a/packages/saber/package.json
+++ b/packages/saber/package.json
@@ -26,6 +26,7 @@
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.5.0",
"@babel/preset-env": "^7.5.4",
+ "@babel/preset-typescript": "^7.6.0",
"@babel/runtime": "^7.5.4",
"@egoist/postcss-loader": "^3.0.2",
"@intervolga/optimize-cssnano-plugin": "^1.0.6",
diff --git a/packages/saber/src/babel/preset.js b/packages/saber/src/babel/preset.js
index 2c1c7144d..34ebb7520 100644
--- a/packages/saber/src/babel/preset.js
+++ b/packages/saber/src/babel/preset.js
@@ -3,7 +3,7 @@ const path = require('path')
const env = process.env.BABEL_ENV || process.env.NODE_ENV
const isEnvTest = env === 'test'
-module.exports = (_, { isServer } = {}) => {
+module.exports = (_, { isServer, alwaysEnableTypeScript } = {}) => {
const presets = [
[
require('@babel/preset-env'),
@@ -21,6 +21,13 @@ module.exports = (_, { isServer } = {}) => {
// Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol']
}
+ ],
+ [
+ require('@babel/preset-typescript'),
+ {
+ jsxPragma: 'h',
+ allExtensions: alwaysEnableTypeScript
+ }
]
]
diff --git a/packages/saber/src/plugins/transformer-components.js b/packages/saber/src/plugins/transformer-components.js
index 30bb02068..61437075c 100644
--- a/packages/saber/src/plugins/transformer-components.js
+++ b/packages/saber/src/plugins/transformer-components.js
@@ -38,7 +38,7 @@ exports.apply = api => {
})
api.transformers.add('js', {
- extensions: ['js'],
+ extensions: ['js', 'jsx', 'ts', 'tsx'],
transform(page) {
const { data } = require('../utils/parseAttributes')(
page.content,
diff --git a/packages/saber/src/vue-renderer/index.js b/packages/saber/src/vue-renderer/index.js
index f8e84a470..1850c4b16 100644
--- a/packages/saber/src/vue-renderer/index.js
+++ b/packages/saber/src/vue-renderer/index.js
@@ -136,11 +136,11 @@ export class VueRenderer {
.options(pageLoaderOptions)
// Get the available extensions for pages
- // Excluding .vue and .js pages because we handled them in their own rules
+ // Excluding .vue .jsx? .tsx? pages because we handled them in their own rules
const { supportedExtensions } = api.transformers
const pageExtensions = supportedExtensions
.map(ext => new RegExp(`\\.${ext}$`))
- .filter(re => !re.test('.js') && !re.test('.vue'))
+ .filter(re => !re.test('.js') && !re.test('.vue') && !re.test('.ts'))
.concat(/\.saberpage$/)
config.module
diff --git a/packages/saber/src/webpack/babel-loader.js b/packages/saber/src/webpack/babel-loader.js
index fe0876f8a..97c12d878 100644
--- a/packages/saber/src/webpack/babel-loader.js
+++ b/packages/saber/src/webpack/babel-loader.js
@@ -53,12 +53,17 @@ module.exports = babelLoader.custom(babel => {
}
}
+ const { filename = '' } = cfg.options
options.presets.unshift(
babel.createConfigItem(
[
require('../babel/preset'),
{
- isServer: customOptions.type === 'server'
+ isServer: customOptions.type === 'server',
+ // Like ts-loader's `appendTsSuffixTo: [/\.vue$/]` option
+ alwaysEnableTypeScript: filename.endsWith('.vue')
+ ? true
+ : undefined
}
],
{
diff --git a/packages/saber/src/webpack/webpack.config.js b/packages/saber/src/webpack/webpack.config.js
index 47653fe64..d64367e94 100644
--- a/packages/saber/src/webpack/webpack.config.js
+++ b/packages/saber/src/webpack/webpack.config.js
@@ -49,7 +49,7 @@ module.exports = (api, { type }) => {
config.module
.rule('js')
- .test(/\.js$/)
+ .test([/\.jsx?$/, /\.tsx?$/])
.include.add(filepath => {
if (api.browserApi.has(filepath)) {
return true
diff --git a/website/pages/index.vue b/website/pages/index.vue
index 2d33b1f57..0376b40ad 100644
--- a/website/pages/index.vue
+++ b/website/pages/index.vue
@@ -53,17 +53,18 @@