Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: jsx in js support [LIBS-633] #871

Merged
merged 5 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]
```
Loading