Skip to content

Commit

Permalink
Merge pull request #127 from KidkArolis/add-ts-support
Browse files Browse the repository at this point in the history
Add TypeScript support
  • Loading branch information
KidkArolis authored Feb 24, 2025
2 parents 49a9c6e + b53becd commit 4ce1e09
Show file tree
Hide file tree
Showing 17 changed files with 3,894 additions and 1,135 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 4.0.0

- Add `typescript` support, compiled by `builtin:swc-loader`
- Use `core-js@3.40` to correctly include latest polyfills
- Switch to `builtin:swc-loader`
- Remove `h` as the default jsx pragma, instead use swc-loader's automatic mode for react

# 3.1.0

- Removed `commander` in favor of native Node.js `parseArgs` util, this might have slight affect on cli flags
Expand Down
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,6 @@ Jetpack provides an ability to proxy requests to your api by specifying `proxy`
- [Differential serving](./docs/07-differential-serving.md)
- [Hot reloading](./docs/08-hot-reloading.md)
- [Comparison to cra, pwa-cli, parcel, etc.](./docs/09-comparison.md)

#### Recipes

- [Adding Flow](./docs/recipe-04-adding-flow.md)
- [Adding Typescript](./docs/recipe-05-adding-typescript.md)
- [Server side rendering](./docs/recipe-06-server-side-rendering.md)

## Motivation
Expand Down
24 changes: 0 additions & 24 deletions docs/recipe-04-adding-flow.md

This file was deleted.

47 changes: 0 additions & 47 deletions docs/recipe-05-adding-typescript.md

This file was deleted.

13 changes: 7 additions & 6 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ module.exports = function options(command = 'dev', { entry = null, flags = {} }

publicPath,

// jsx pragma
jsx: options.jsx || jsx(dir),
// are we using react
react: options.react || isUsingReact(dir),

// hot reloading
hot: options.hot === undefined ? true : options.hot,
Expand Down Expand Up @@ -184,7 +184,8 @@ function readConfigFromFile(dir, configFilePath) {
if (!configFilePath) return {}
const configPath = path.join(dir, configFilePath)
const exists = fs.pathExistsSync(configPath)
return exists ? require(configPath) : {}
const config = exists ? require(configPath) : {}
return config.default ? config.default : config
}

function pkg(dir) {
Expand All @@ -195,16 +196,16 @@ function pkg(dir) {
}
}

function jsx(dir) {
function isUsingReact(dir) {
try {
requireRelative.resolve('react', dir)
return 'React.createElement'
return true
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err
}
}
return 'h'
return false
}

function assets({ publicPath, entrypoints }) {
Expand Down
10 changes: 7 additions & 3 deletions lib/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ const RetryChunkLoadPlugin = require('./retryChunkLoadPlugin.js')

const plugins = {
js: require('./webpack.js'),
ts: require('./webpack.ts'),
react: require('./webpack.react'),
hot: require('./webpack.hot'),
css: require('./webpack.css'),
scss: require('./webpack.scss'),
assets: require('./webpack.assets'),
hot: require('./webpack.hot')
assets: require('./webpack.assets')
}

module.exports = async function config(options, log) {
Expand Down Expand Up @@ -81,10 +83,12 @@ async function createConfig(options, log) {
}

await plugins.js(config, options)
await plugins.ts(config, options)
await plugins.react(config, options)
await plugins.hot(config, options)
await plugins.scss(config, options)
await plugins.css(config, options)
await plugins.assets(config, options)
await plugins.hot(config, options)

if (options.rspack) {
config = (await options.rspack(config, options)) || config
Expand Down
45 changes: 1 addition & 44 deletions lib/webpack.hot.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const rspack = require('@rspack/core')
const requireRelative = require('require-relative')
const ReactRefreshPlugin = require('@rspack/plugin-react-refresh')

module.exports = (config, options) => {
Expand All @@ -12,51 +11,9 @@ module.exports = (config, options) => {
].concat(config.entry[e])
})

const usingReact = isUsingReact(options.dir)
const usingReactDOM = isUsingReactDOM(options.dir)

if (usingReact && usingReactDOM) {
// important for when jetpack is used without installing it locally
config.resolve.alias.react = usingReact
config.resolve.alias['react-dom'] = usingReactDOM

if (options.react) {
config.plugins.push(new ReactRefreshPlugin())
config.resolve.alias['react-refresh/runtime'] = require.resolve('react-refresh/runtime')
config.module.rules[0].oneOf.forEach((rule) => {
if (rule.use) {
rule.use.forEach((loader) => {
if (loader.loader === require.resolve('swc-loader')) {
loader.options.jsc.transform.react = {
runtime: 'automatic',
development: true,
refresh: true
}
}
})
}
})
}
}
}

function isUsingReact(dir) {
try {
return requireRelative.resolve('react', dir).replace(/\/index.js$/, '')
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err
}
}
return false
}

function isUsingReactDOM(dir) {
try {
return requireRelative.resolve('react-dom', dir).replace(/\/index.js$/, '')
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err
}
}
return false
}
8 changes: 4 additions & 4 deletions lib/webpack.js.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ module.exports = (config, options) => {
exclude: /(node_modules)/,
use: [
{
loader: require.resolve('swc-loader'),
loader: 'builtin:swc-loader',
options: {
env: {
targets: browsers.query(options),
coreJs: 3,
coreJs: '3.40',
mode: 'usage'
},
jsc: {
Expand Down Expand Up @@ -48,11 +48,11 @@ module.exports = (config, options) => {
},
use: [
{
loader: require.resolve('swc-loader'),
loader: 'builtin:swc-loader',
options: {
env: {
targets: browsers.query(options),
coreJs: 3,
coreJs: '3.40',
mode: 'usage'
},
jsc: {
Expand Down
50 changes: 50 additions & 0 deletions lib/webpack.react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const requireRelative = require('require-relative')

module.exports = (config, options) => {
if (options.react) {
const reactPath = getReactPath(options.dir)
if (reactPath) {
config.resolve.alias.react = reactPath
}
const reactDOMPath = getReactDOMPath(options.dir)
if (reactDOMPath) {
config.resolve.alias['react-dom'] = reactDOMPath
}

config.module.rules[0].oneOf.forEach((rule) => {
if (rule.use) {
rule.use.forEach((loader) => {
if (loader.loader === require.resolve('swc-loader') || loader.loader === 'builtin:swc-loader') {
loader.options.jsc.transform.react = {
runtime: 'automatic',
development: !options.production,
refresh: !options.production && options.hot
}
}
})
}
})
}
}

function getReactPath(dir) {
try {
return requireRelative.resolve('react', dir).replace(/\/index.js$/, '')
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err
}
}
return null
}

function getReactDOMPath(dir) {
try {
return requireRelative.resolve('react-dom', dir).replace(/\/index.js$/, '')
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err
}
}
return null
}
30 changes: 30 additions & 0 deletions lib/webpack.ts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const browsers = require('./browsers')

module.exports = (config, options) => {
config.module.rules[0].oneOf.push({
test: /\.(ts|tsx)$/,
exclude: /(node_modules)/,
use: [
{
loader: 'builtin:swc-loader',
options: {
env: {
targets: browsers.query(options),
coreJs: '3.40',
mode: 'usage'
},
jsc: {
parser: {
syntax: 'typescript',
exportDefaultFrom: true,
jsx: true
},
externalHelpers: true,
transform: {}
},
isModule: 'unknown'
}
}
]
})
}
Loading

0 comments on commit 4ce1e09

Please # to comment.