I’m trying to set up my shared package to allow importing modules from specific subpaths (e.g., @shared/utils, @shared/hooks). To achieve this, I’ve configured my package.json as follows:
// package.json
{
// ..
"exports": {
".": {
"default": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./utils": {
"default": "./dist/utils/index.js",
"types": "./dist/utils/index.d.ts"
},
// ..
}
}
I’m using esbuild as my module bundler, with the following configuration:
// build.mjs
const libBuildOptions = {
entryPoints: ['./src/**/*'],
outdir: 'dist',
tsconfig: './tsconfig.json',
target: 'es6',
plugins: [nodeExternalsPlugin()],
define,
format: 'esm',
outExtension: { '.js': '.js' },
sourcemap: true
}
const build = async () => {
await esbuild.build(libBuildOptions);
const execAsync = promisify(exec);
await execAsync('tsc --emitDeclarationOnly --outDir dist');
};
My source files are structured as follows:
// src/index.ts
export * from './utils';
// ..
// src/utils/index.ts
export * from './testSentry';
export * from './config';
export * from './theme';
With this setup, when I try to import modules from this shared package in other packages, I can only import from the @shared path, not from subpaths like @shared/utils.
Is there a solution to allow importing from subpaths as intended?
Any help or suggestions would be greatly appreciated. Thank you!
- Configured
package.json
withexports
field to specify subpaths:
{
"exports": {
".": {
"default": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./utils": {
"default": "./dist/utils/index.js",
"types": "./dist/utils/index.d.ts"
}
}
}
- Set up esbuild configuration in
build.mjs
:
const libBuildOptions = {
entryPoints: ['./src/**/*'],
outdir: 'dist',
tsconfig: './tsconfig.json',
target: 'es6',
plugins: [nodeExternalsPlugin()],
format: 'esm',
outExtension: { '.js': '.js' },
sourcemap: true
}
const build = async () => {
await esbuild.build(libBuildOptions);
await execAsync('tsc --emitDeclarationOnly --outDir dist');
};
- Structured the source files to export from subpaths:
// src/index.ts
export * from './utils';
// src/utils/index.ts
export * from './testSentry';
export * from './config';
export * from './theme';
- Tried specifying direct file paths in
exports
:
{
"exports": {
"./utils/date.js": {
"default": "./dist/utils/date.js",
"types": "./dist/utils/date.d.ts"
}
}
}
- Investigated TypeScript configuration:
- Checked if
tsconfig.json
hadmoduleResolution
set tonode16
ornodenext
. - Considered changing
moduleResolution
tobundler
.
- Checked if
I was expecting to be able to import modules from subpaths like @shared/utils
or @shared/hooks
, but the imports are only working from the main @shared
path. I can import from @extension/shared/dist/utils
, but not from @extension/shared/utils
as intended.