Skip to content

Commit

Permalink
fix: handle jsx in js support [LIBS-633] (#871)
Browse files Browse the repository at this point in the history
* fix: jsx-in-js handling

* docs: allowJsxInJs option

* chore: typo

* feat: add warning logs
  • Loading branch information
KaiVandivier authored Oct 1, 2024
1 parent 313daae commit 595a35d
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 43 deletions.
67 changes: 35 additions & 32 deletions cli/config/makeViteConfig.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import react from '@vitejs/plugin-react'
import {
defineConfig,
mergeConfig,
searchForWorkspaceRoot,
transformWithEsbuild,
} from 'vite'
Expand All @@ -17,28 +18,33 @@ import dynamicImport from 'vite-plugin-dynamic-import'
* Vite normally throws an error when JSX syntax is used in a file without a
* .jsx or .tsx extension. This is by design, in order to improve transform
* performance by not parsing JS files for JSX.
* This plugin is 1 of 2 config options that allow JSX to be used in
* .js or .ts files -- the options in `optimizeDeps` below are part 2.
*
* This plugin and the `optimizeDeps` options in this config object,
* along with the `jsxRuntime: 'classic'` option in the React plugin of the main
* config, can enable support for JSX in .js files. This config object is
* merged with the main config if the `--allowJsxInJs` flag is passed
* to the CLI
*
* NB: State-preserving HMR will not work on React components unless they have
* a .jsx or .tsx extension though, unfortunately
*
* todo: deprecate -- this and optimize deps below have a performance cost
* on startup
* todo: deprecate -- this config has a performance cost, especially on startup
*/
const jsxInJSPlugin = {
name: 'treat-js-files-as-jsx',
async transform(code, id) {
if (!id.match(/src\/.*\.js$/)) {
return null
}
// todo: consider JSX warning if </ or />
// Use the exposed transform from vite, instead of directly
// transforming with esbuild
return transformWithEsbuild(code, id, {
loader: 'jsx',
jsx: 'automatic',
})
const jsxInJsConfig = {
plugins: [{
name: 'treat-js-files-as-jsx',
async transform(code, id) {
if (!id.match(/src\/.*\.js$/)) {
return null
}
// Use the exposed transform from vite, instead of directly
// transforming with esbuild
return transformWithEsbuild(code, id, {
loader: 'jsx',
jsx: 'automatic',
})
},
}],
optimizeDeps: {
force: true,
esbuildOptions: { loader: { '.js': 'jsx' } },
},
}

Expand Down Expand Up @@ -107,8 +113,8 @@ const getBuildInputs = (config, paths) => {
}

// https://vitejs.dev/config/
export default ({ paths, config, env, host }) => {
return defineConfig({
export default ({ paths, config, env, host, force, allowJsxInJs }) => {
const baseConfig = defineConfig({
// Need to specify the location of the app root, since this CLI command
// gets run in a different directory than the bootstrapped app
root: paths.shell,
Expand Down Expand Up @@ -153,8 +159,6 @@ export default ({ paths, config, env, host }) => {
},

plugins: [
// Allow JSX in .js files pt. 1
jsxInJSPlugin,
/**
* Allows the dynamic import of `moment/dist/locale/${locale}`
* in /adapter/src/utils/localeUtils.js.
Expand All @@ -164,16 +168,15 @@ export default ({ paths, config, env, host }) => {
dynamicImport(),
react({
babel: { plugins: ['styled-jsx/babel'] },
// Enables HMR for .js files:
jsxRuntime: 'classic',
// todo: deprecate with other jsx-in-js config
// This option allows HMR of JSX-in-JS files,
// but it isn't possible to add with merge config:
jsxRuntime: allowJsxInJs ? 'classic' : 'automatic',
}),
],

// Allow JSX in .js pt. 2
// todo: deprecate - has a performance cost on startup
optimizeDeps: {
force: true,
esbuildOptions: { loader: { '.js': 'jsx' } },
},
optimizeDeps: { force },
})

return allowJsxInJs ? mergeConfig(baseConfig, jsxInJsConfig) : baseConfig
}
21 changes: 20 additions & 1 deletion cli/src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const handler = async ({
verify,
force,
pack: packAppOutput,
allowJsxInJs,
}) => {
const paths = makePaths(cwd)

Expand Down Expand Up @@ -136,7 +137,20 @@ const handler = async ({
'../../config/makeViteConfig.mjs'
)
const env = getEnv({ config, ...appParameters })
const viteConfig = createConfig({ paths, config, env })
if (allowJsxInJs) {
reporter.warn(
'Adding Vite config to allow JSX syntax in .js files. This is deprecated and will be removed in future versions.'
)
reporter.warn(
'Consider using the migration script `yarn d2-app-scripts migrate js-to-jsx` to rename your files to use .jsx extensions.'
)
}
const viteConfig = createConfig({
paths,
config,
env,
allowJsxInJs,
})
await build(viteConfig)

if (config.pwa.enabled) {
Expand Down Expand Up @@ -235,6 +249,11 @@ const command = {
'Build in standalone mode (overrides the d2.config.js setting)',
default: undefined,
},
allowJsxInJs: {
type: 'boolean',
description:
'Add Vite config to handle JSX in .js files. DEPRECATED: Will be removed in @dhis2/cli-app-scripts v13. Consider using the migration script `d2-app-scripts migrate js-to-jsx` to avoid needing this option',
},
},
handler,
}
Expand Down
25 changes: 23 additions & 2 deletions cli/src/commands/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const handler = async ({
proxy,
proxyPort,
host,
allowJsxInJs,
}) => {
const paths = makePaths(cwd)

Expand Down Expand Up @@ -131,7 +132,22 @@ const handler = async ({
const { default: createConfig } = await import(
'../../config/makeViteConfig.mjs'
)
const viteConfig = createConfig({ config, paths, env, host })
if (allowJsxInJs) {
reporter.warn(
'Adding Vite config to allow JSX syntax in .js files. This is deprecated and will be removed in future versions.'
)
reporter.warn(
'Consider using the migration script `yarn d2-app-scripts migrate js-to-jsx` to rename your files to use .jsx extensions.'
)
}
const viteConfig = createConfig({
config,
paths,
env,
host,
force,
allowJsxInJs,
})
const server = await createServer(viteConfig)

const location = config.entryPoints.plugin
Expand Down Expand Up @@ -176,7 +192,7 @@ const command = {
force: {
type: 'boolean',
description:
'Force updating the app shell. Normally, this is only done when a new version of @dhis2/cli-app-scripts is detected',
'Force updating the app shell; normally, this is only done when a new version of @dhis2/cli-app-scripts is detected. Also passes the --force option to the Vite server to reoptimize dependencies',
},
port: {
alias: 'p',
Expand All @@ -199,6 +215,11 @@ const command = {
description:
'Exposes the server on the local network. Can optionally provide an address to use. [boolean or string]',
},
allowJsxInJs: {
type: 'boolean',
description:
'Add Vite config to handle JSX in .js files. DEPRECATED: Will be removed in @dhis2/cli-app-scripts v13. Consider using the migration script `d2-app-scripts migrate js-to-jsx` to avoid needing this option',
},
},
handler,
}
Expand Down
4 changes: 4 additions & 0 deletions docs/scripts/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ Options:
--watch Watch source files for changes [boolean] [default: false]
--standalone Build in standalone mode (overrides the d2.config.js setting)
[boolean]
--allowJsxInJs Add Vite config to handle JSX in .js files. DEPRECATED: Will
be removed in @dhis2/cli-app-scripts v13. Consider using the
migration script `d2-app-scripts migrate js-to-jsx` to avoid
needing this option [boolean]
```
22 changes: 14 additions & 8 deletions docs/scripts/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,19 @@ Global Options:
--config Path to JSON config file

Options:
--cwd working directory to use (defaults to cwd)
--force Force updating the app shell. Normally, this is only done when a
new version of @dhis2/cli-app-scripts is detected [boolean]
--port, -p The port to use when running the development server
--cwd working directory to use (defaults to cwd)
--force Force updating the app shell; normally, this is only done when
a new version of @dhis2/cli-app-scripts is detected. Also
passes the --force option to the Vite server to re-optimize
dependencies [boolean]
--port, -p The port to use when running the development server
[number] [default: 3000]
--proxy, -P The remote DHIS2 instance the proxy should point to [string]
--proxyPort The port to use when running the proxy [number] [default: 8080]
--host Exposes the server on the local network. Can optionally provide
an address to use. [boolean or string]
--proxy, -P The remote DHIS2 instance the proxy should point to [string]
--proxyPort The port to use when running the proxy[number] [default: 8080]
--host Exposes the server on the local network. Can optionally
provide an address to use. [boolean or string]
--allowJsxInJs Add Vite config to handle JSX in .js files. DEPRECATED: Will
be removed in @dhis2/cli-app-scripts v13. Consider using the
migration script `d2-app-scripts migrate js-to-jsx` to avoid
needing this option [boolean]
```

0 comments on commit 595a35d

Please sign in to comment.