mirror of
https://github.com/hanzoai/rfc.git
synced 2026-10-30 18:23:14 +00:00
The WIP commit added the gui runtime (GuiProvider + an @hanzo/ui Button) and the
build stopped compiling:
Module parse failed: Unexpected token (13:12)
./…/react-native/Libraries/Utilities/codegenNativeComponent.js
Import trace:
@hanzo/ui/dist/backends/gui/checkbox.js
→ @hanzogui/lucide-icons-2 → react-native-svg/lib/module/fabric/…
A react-native package publishes `Foo.js` beside `Foo.web.js` and imports
`./Foo` extensionless, leaving the choice to the resolver. Webpack's default
extension order has no `.web.*` in it, so on web it silently picked the NATIVE
file — react-native-svg's fabric components, which import react-native Flow
source no bundler can parse. The `react-native$` alias never applied: the
specifier being resolved was `./ReactNativeSVG`, not `react-native`.
Prepending the web extensions is the whole fix; the same four lines carry the
same comment in app-std/next.config.mjs, which hit this first.
$ pnpm build
✓ Compiled successfully in 44s
✓ Generating static pages (11/11)
✓ Exporting (2/2)
Co-authored-by: Hanzo Dev <[email protected]>
54 lines
2.2 KiB
JavaScript
54 lines
2.2 KiB
JavaScript
// Plain .mjs, not next.config.ts — deliberately.
|
|
//
|
|
// Next loads a TypeScript config through the TypeScript compiler API, so a .ts
|
|
// config would make config LOADING depend on which TypeScript is installed. As
|
|
// ESM there is nothing to resolve: Next reads this file natively and the type
|
|
// comes from the JSDoc annotation.
|
|
//
|
|
// That dependency is not hypothetical. Next also reads `compilerOptions.paths`
|
|
// through `ts.parseJsonConfigFileContent`, and TypeScript 7 — the native Go
|
|
// compiler — ships no JS API at all (`require('typescript')` is just
|
|
// `{version, versionMajorMinor}`). Under 7 every `@/…` import fails to resolve
|
|
// and the type-check step silently disappears, so this repo stays on 5.x until
|
|
// Next stops linking the API. See LLM.md.
|
|
|
|
/** @type {import('next').NextConfig} */
|
|
const config = {
|
|
reactStrictMode: true,
|
|
// The whole site is prerendered from markdown on disk; there is no runtime.
|
|
output: 'export',
|
|
images: { unoptimized: true },
|
|
trailingSlash: true,
|
|
|
|
// @hanzo/gui and the component layer on top of it ship untranspiled ESM that
|
|
// still names `react-native`. On web that name IS react-native-web, which is
|
|
// the alias below; `transpilePackages` is what makes Next compile the source
|
|
// rather than hand raw ESM to the server runtime.
|
|
transpilePackages: ['@hanzo/gui', '@hanzo/ui', '@hanzogui/config', 'react-native-web'],
|
|
|
|
webpack: (webpackConfig) => {
|
|
webpackConfig.resolve.alias = {
|
|
...webpackConfig.resolve.alias,
|
|
'react-native$': 'react-native-web',
|
|
};
|
|
|
|
// PREPEND the web extensions. A react-native package publishes `Foo.js`
|
|
// beside `Foo.web.js` and imports `./Foo` extensionless, leaving the choice
|
|
// to the resolver — so the default extension order silently picks the
|
|
// NATIVE file on web. That is how @hanzo/ui reaches react-native-svg's
|
|
// fabric `*NativeComponent.js`, which imports react-native Flow source
|
|
// webpack cannot parse ("Module parse failed: Unexpected token").
|
|
webpackConfig.resolve.extensions = [
|
|
'.web.tsx',
|
|
'.web.ts',
|
|
'.web.jsx',
|
|
'.web.js',
|
|
...webpackConfig.resolve.extensions,
|
|
];
|
|
|
|
return webpackConfig;
|
|
},
|
|
};
|
|
|
|
export default config;
|