typeorm-seeding
typeorm-seeding copied to clipboard
Cannot use import statement outside a module
After upgrading to latest release (7.0.0), I got this error:
/Users/user/Desktop/project/node_modules/@jorgebodega/typeorm-seeding/dist/cli.js:2
import { bootstrap } from './commands/seed.command';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at internalCompileFunction (node:internal/vm:77:18)
at wrapSafe (node:internal/modules/cjs/loader:1290:20)
at Module._compile (node:internal/modules/cjs/loader:1342:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1437:10)
at Object.require.extensions.<computed> [as .js] (/Users/user/Desktop/project/node_modules/ts-node/src/index.ts:1608:43)
at Module.load (node:internal/modules/cjs/loader:1212:32)
at Function.Module._load (node:internal/modules/cjs/loader:1028:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:142:12)
at phase4 (/Users/user/Desktop/project/node_modules/ts-node/src/bin.ts:649:14)
at bootstrap (/Users/user/Desktop/project/node_modules/ts-node/src/bin.ts:95:10)
Hey @nodegin you can use this lib as an executor, mine was fixed when use this lib.
package.json:
"typeorm": "tsx ./node_modules/typeorm/cli",
"seeding": "tsx ./node_modules/@jorgebodega/typeorm-seeding/dist/cli",
"migration:generate": "npm run typeorm -- -d ./src/db/typeorm.config.ts migration:generate ./src/db/migrations/$npm_config_name",
"migration:run": "npm run typeorm -- -d ./src/db/typeorm.config.ts migration:run",
"migration:revert": "npm run typeorm -- -d ./src/db/typeorm.config.ts migration:revert",
"seed:run": "npm run seeding -- seed -d ./src/db/typeorm.config.ts ./src/db/seeds/*.ts"
terminal:
npm run seed:run
v7 switched from CommonJS to ESM. It is not mentioned in the breaking changes, but it is a breaking change for projects that are using CommonJS
As far as I tried, I did not change anything to be ESM-only (TypeORM is still supporting CommonJS).
If you are sure of this problem, a PR would be appreciated.
Introduced by PR #303 in tsconfig.json
by changing:
compilerOptions.module
: node16
(v6) -> es2022
(v7)
This change replaced the require
s with import
s. It's true that package.json
doesn't contain type: module
, so the package is still CommonJS, but the scripts are using ESM imports.
Probably the best option for consistency would be to use node16
or nodenext
when transpiling: https://www.typescriptlang.org/tsconfig#module. If you take a look at @tsconfig/node20
, they are using module: node16
.
Normally since it's a CLI tool, it shouldn't matter whether it's CommonJS or ESM, but it does if you are forced to call dist/cli.js
directly from your own project. We do that because both the seeds and the typeorm config are written in TypeScript, so we are executing e.g. ts-node typeorm-seeding/dist/cli.js *.seed.ts -d ormconfig.ts
.
Later edit: ts-node
supports --esm
(and it also provides ts-node-esm
), so probably not a big deal, will need to check if it solves the issue for me.
ts-node --esm
does not work (obviously) and tsx
doesn't work either because it uses esbuild
which is not good at transpiling TypeScript (especially decorators in the TypeORM entities).
I'll update the tsconfig.json
to use tsconfig/node18
probably and submit a PR.
Since neither ts-node
nor tsx
are working and since ESM imports in CommonJS modules are not allowed anyway, I opened PR #325 to set the TypeScript target module type back to node16
(auto-detect, based on package.json
config) instead of es2022
(forced ESM). This changes the ESM import
s back to CJS require
s and solves this issue.
In general, I would not change from node16
to anything else since this is the option that detects the module type automatically (unless multiple compilation targets are needed, e.g. to publish both CJS and ESM in one package).
@jorgebodega/typeorm-factory
has the same issue.
You may don't need anything at all. at least some typescript runner eg bun
// create-users.ts
import dataSource from "@demo-app/backend/db/seeds/datasource";
import { UsersEntity } from "@demo-app/backend/src/users/users.entity";
const users: Partial<UsersEntity>[] = [ {
email: "[email protected]",
password: "test",
} ];
await dataSource.createEntityManager().save(
users.map( user => Object.assign( new UsersEntity(), user ) )
);
// datasource.ts
import { DataSource } from "typeorm";
import DatabaseConfig from "@demo-app/backend/config/database.config";
const dataSource = await ( new DataSource( DatabaseConfig ) ).initialize();
export default dataSource;
// database.config.ts
import { UsersEntity } from "@demo-app/backend/src/users/users.entity";
import type { TypeOrmModuleOptions } from "@nestjs/typeorm";
const config : TypeOrmModuleOptions = {
type: "sqlite",
database: "db/database.sqlite",
logging: "all",
logger: "advanced-console",
};
function shouldSynchronize( config: TypeOrmModuleOptions ) {
// If database exists, do not synchronize
if ( "sqlite" === config.type ) {
return ! require( "fs" ).existsSync( config.database );
}
// TODO: Implement for other database types
return false;
}
export default {
...config,
entities: [ UsersEntity ],
synchronize: shouldSynchronize( config ),
};
bun run --bun create-users.ts
FYI bun
doesn't work properly with TypeORM.
Or rather, TypeORM has some incorrect package.json
config that makes bun
interpret imports incorrectly. See https://github.com/oven-sh/bun/issues/7633 or a few other tickets in the bun
repo.
Hey @nodegin you can use this lib as an executor, mine was fixed when use this lib.
package.json:
"typeorm": "tsx ./node_modules/typeorm/cli", "seeding": "tsx ./node_modules/@jorgebodega/typeorm-seeding/dist/cli", "migration:generate": "npm run typeorm -- -d ./src/db/typeorm.config.ts migration:generate ./src/db/migrations/$npm_config_name", "migration:run": "npm run typeorm -- -d ./src/db/typeorm.config.ts migration:run", "migration:revert": "npm run typeorm -- -d ./src/db/typeorm.config.ts migration:revert", "seed:run": "npm run seeding -- seed -d ./src/db/typeorm.config.ts ./src/db/seeds/*.ts"
terminal:
npm run seed:run
Thank you, we can follow this temp solution to fix this
tsx
and bun
didn't work for my for the reasons specified above. My current solution was to update to 7.1.0-next.1 and patch the dynamic import in commandUtils.js
until this is properly fixed.
diff --git a/dist/utils/commandUtils.js b/dist/utils/commandUtils.js
index 0a922d09f28843382e947501307f775b4181a1f3..febe6d3d13660918072d81c6de0aad19228f1356 100644
--- a/dist/utils/commandUtils.js
+++ b/dist/utils/commandUtils.js
@@ -8,7 +8,7 @@ async function loadDataSource(dataSourceFilePath) {
return CommandUtils_1.CommandUtils.loadDataSource(dataSourceFilePath);
}
async function loadSeeders(seederPaths) {
- const seederFileExports = (await Promise.all(seederPaths.map((seederFile) => import(seederFile))))
+ const seederFileExports = (await Promise.all(seederPaths.map((seederFile) => Promise.resolve().then(() => require(seederFile)))))
.map((seederExport) => seederExport.default?.default ?? seederExport.default)
.filter((seederExport) => Boolean(seederExport));
if (seederFileExports.length === 0) {
Instead of the dynamic import, the actual solution would be to use importOrRequireFile
from typeorm/util/ImportUtils
- then the seeders would be loaded in the same way ormconfig, entities, subscribers and migrations are loaded.
Or even better, we could completely rely on TypeORM for loading the classes from the globs, using importClassesFromDirectories
(from typeorm/util/DirectoryExportedClassesLoader
).
I just opened two PRs, #338 and #339.
I prefer #339 since it relies on more on TypeORM build-in functions, so there's less code in this repo to maintain.