Skip to content

Commit

Permalink
fix: node+browser compatible ES module import paths (#378)
Browse files Browse the repository at this point in the history
The packages that export ES modules do not have a `.js` extension on the
import paths, which means that the import path does not match an actual
file path (since the latter do have a `.js` extension). This means they
cannot be properly resolved by Node.js or the browser.

However, since we're using TypeScript to transpile, and we're using the
legacy "node" module resolution, the import paths are preserved and end
up not having a `.js` extension, while the transpiled files to have it.

There are two main ways to deal with this:

1. Use TS configuration `{"module":"esnext","moduleResolution":"bundler"}`
   and use a bundler that produces import paths matching an actual file.
   Note: using TypeScript in this case would leave the imports as-is
   and require users to use a bundler, so it would not constitute an
   ES module that just works with node/browser, which is the problem we
   actually set out to solve.
2. Use TS configuration `{"module":"nodenext","moduleResolution":"nodenext"}`
   and use `{"type":"module"}` in package.json. This will instruct tsc to
   produce output that matches the package configuration, so ES module in
   this case.

The advantage with (1) is that it requires no addition of a `.js`
extension to the imports in the .ts(x) source files. Unfortunately this
requires TS 5 (we currently use TS 4) _and_ the use of a bundler to
build (which we currently do not use). The advantage with (2) is that it
requires no changes to how we build, but it does required adding a `.js`
extension to all import paths in the source code.

Since addition of a bundler adds a layer of complexity in maintenance
for a repository that should be easily accessible, it seems option (2) is
preferable (and also can be done without having to do a major TS ugprade
first).
  • Loading branch information
steabert authored Feb 7, 2025
1 parent e94d629 commit 22da89e
Show file tree
Hide file tree
Showing 15 changed files with 37 additions and 39 deletions.
2 changes: 1 addition & 1 deletion components/empty-view/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"root": true,
"ignorePatterns": ["lib", "**/*.js"],
"parserOptions": {
"project": ["./tsconfig.src.json"]
"project": ["./tsconfig.json"]
}
}
17 changes: 9 additions & 8 deletions components/empty-view/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@
},
"license": "MIT",
"author": "Axis Communications AB",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib"
],
"type": "module",
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./lib/index.js"
}
},
"files": ["lib"],
"scripts": {
"prebuild": "pnpm run -C ../../illustrations build",
"build": "pnpm prebuild && pnpm build:cjs && pnpm build:esm",
"build:cjs": "tsc --module commonjs --outDir lib/cjs",
"build:esm": "tsc",
"build": "pnpm prebuild && tsc",
"check:unused-deps": "depcheck . --config=depcheck.yml",
"lint": "tsc --noEmit && eslint . --cache"
},
Expand Down
2 changes: 1 addition & 1 deletion components/empty-view/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import {
UnderConstructionDark,
UnderConstructionLight,
} from "@axiscommunications/fluent-illustrations";
import { IllustrationKind } from "./types";
import { IllustrationKind } from "./types.js";

export const Illustration: Record<
IllustrationKind,
Expand Down
2 changes: 1 addition & 1 deletion components/empty-view/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ export {
MainEmptyView,
PanelEmptyView,
SubmenuEmptyView,
} from "./view";
} from "./view.js";
2 changes: 1 addition & 1 deletion components/empty-view/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
shorthands,
tokens,
} from "@fluentui/react-components";
import { HtmlDivAttributesRestProps } from "./types";
import { HtmlDivAttributesRestProps } from "./types.js";

export const useStyles = makeStyles({
container: {
Expand Down
6 changes: 3 additions & 3 deletions components/empty-view/src/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import {

import { useMediaQuery } from "@axiscommunications/fluent-hooks";

import { useContainerStyle, useStyles } from "./styles";
import { useContainerStyle, useStyles } from "./styles.js";
import {
ContentProps,
EmptyViewProps,
HtmlDivAttributesRestProps,
} from "./types";
import { Illustration } from "./constants";
} from "./types.js";
import { Illustration } from "./constants.js";

function ContainerSpacious(
{ children, className, ...rest }: PropsWithChildren<
Expand Down
5 changes: 4 additions & 1 deletion components/empty-view/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"extends": "./tsconfig.src.json",
"extends": "../../tsconfig.base.json",
"include": ["src"],
"compilerOptions": {
"module": "nodenext",
"moduleResolution": "nodenext",
"outDir": "lib"
}
}
4 changes: 0 additions & 4 deletions components/empty-view/tsconfig.src.json

This file was deleted.

6 changes: 3 additions & 3 deletions components/password-input/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@
},
"license": "MIT",
"author": "Axis Communications AB",
"type": "module",
"exports": {
".": {
"types": "./lib/index.d.ts",
"require": "./lib/cjs/index.js",
"import": "./lib/index.js"
}
},
"main": "lib/cjs/index.js",
"module": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib"
],
"files": ["lib"],
"scripts": {
"build": "pnpm build:cjs && pnpm build:esm",
"build:cjs": "tsc --module commonjs --outDir lib/cjs",
Expand Down
6 changes: 3 additions & 3 deletions components/password-input/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { PasswordInput } from "./password-input";
export { usePasswordInputStyles } from "./password-input.styles";
export type { PasswordInputProps } from "./password-input.types";
export { PasswordInput } from "./password-input.js";
export { usePasswordInputStyles } from "./password-input.styles.js";
export type { PasswordInputProps } from "./password-input.types.js";
4 changes: 2 additions & 2 deletions components/password-input/src/password-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
} from "@fluentui/react-components";
import { EyeOffRegular, EyeRegular } from "@fluentui/react-icons";

import { PasswordInputProps } from "./password-input.types";
import { usePasswordInputStyles } from "./password-input.styles";
import { PasswordInputProps } from "./password-input.types.js";
import { usePasswordInputStyles } from "./password-input.styles.js";

export const PasswordInput: ForwardRefComponent<PasswordInputProps> = React
.forwardRef((props: PasswordInputProps, ref) => {
Expand Down
8 changes: 2 additions & 6 deletions hooks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,18 @@
},
"license": "MIT",
"author": "Axis Communications AB",
"type": "module",
"exports": {
".": {
"require": "./lib/cjs/index.js",
"import": "./lib/index.js"
}
},
"main": "lib/cjs/index.js",
"module": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib"
],
"scripts": {
"build": "pnpm build:cjs && pnpm build:esm",
"build:cjs": "tsc --module commonjs --outDir lib/cjs",
"build:esm": "tsc",
"build": "tsc",
"check:unused-deps": "depcheck . --config=depcheck.yml",
"lint": "tsc --noEmit && eslint . --cache"
},
Expand Down
4 changes: 2 additions & 2 deletions hooks/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { useMediaQuery } from "./use-media-query";
export { usePageController } from "./use-page-controller";
export { useMediaQuery } from "./use-media-query.js";
export { usePageController } from "./use-page-controller.js";
2 changes: 2 additions & 0 deletions hooks/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"module": "nodenext",
"moduleResolution": "nodenext",
"outDir": "lib"
},
"include": ["src"],
Expand Down
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 22da89e

Please sign in to comment.