I have a nest app that is using monorepo mode. I would like to take advantage of the new repl feature that was released in nest 9.0+.
My directory structure looks as such:
apps/
--inventory-ops/src/app.module
--ticket-office/src/app.module
I have followed the instructions found in the docs creating a repl.ts, but when I run the repl commannd:
npm run start -- --entryFile repl
I get this error output:
Error: Cannot find module '/dist/apps/ticket-office/repl'
Looking at my dist folder, the only build target is main.js, which would explain it not being able to find the repl module. Do I need to update something in my webpack config to make sure repl.ts gets built as well? Any help would be appreciated.
I managed to solve this by adding a new project in nest-cli.json, for example:
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "#nestjs/schematics",
"sourceRoot": "apps/gateway/src",
"monorepo": true,
"root": "apps/gateway",
"compilerOptions": {
"webpack": true,
"tsConfigPath": "apps/gateway/tsconfig.app.json"
},
"projects": {
"gateway": {
"type": "application",
"root": "apps/gateway",
"entryFile": "main",
"sourceRoot": "apps/gateway/src",
"compilerOptions": {
"tsConfigPath": "apps/gateway/tsconfig.app.json"
}
},
"ticket-office": {
"type": "application",
"root": "apps/ticket-office",
"entryFile": "main",
"sourceRoot": "apps/ticket-office/src",
"compilerOptions": {
"tsConfigPath": "apps/ticket-office/tsconfig.app.json"
}
},
"ticket-office:repl": { // <<--- HERE
"type": "application",
"root": "apps/ticket-office",
"entryFile": "repl", // <<-- HERE
"sourceRoot": "apps/ticket-office/src",
"compilerOptions": {
"tsConfigPath": "apps/ticket-office/tsconfig.app.json"
}
},
}
}
Then you can run nest start ticket-office:repl
I hope this helps.
EDIT:
Adapted the answer to your question.
Try to run this:
nest start <your-app> --config nest-cli.json --debug --watch -- --entryFile repl
I faced the same issue and this worked for me.
I don't really know why NestJS take repl file into consideration for building only when explicitly the cli config is provided. It's probably a bug with the CLI.
Alternative
Also, you can add a custom parameter to your command and start the REPL mode conditionally:
script:
nest start <your-app> --watch repl
main.ts file:
async function bootstrap() {
if (process.argv[process.argv.length - 1] === 'repl') {
return repl(AppModule);
}
// Non REPL mode Nest app initialisation
...
}
bootstrap();
Related
I have a problem that is similar to the one described in Building library with imports from another library using NX Monorepo.
Using nx monorepo with a node app and a library. The app is built with #nrwl/js:tsc (not webpack as it is by default) and then executed using #nrwl/node:node. This is what the project.json looks like:
"build": {
"executor": "#nrwl/js:tsc",
"outputs": ["{options.outputPath}"],
"options": {
"main": "apps/dep/src/main.ts",
"outputPath": "dist/apps/dep",
"tsConfig": "apps/dep/tsconfig.app.json"
}
},
"serve": {
"executor": "#nrwl/node:node",
"options": {
"buildTarget": "dep:build"
}
},
Importing anything from another library causes a problem with the build due to files not being under rootDir:
import { MyEnum } from '#zorro/types';
This I resolved using the advice from the question above, adding the following settings to tsconfig.app.json:
"compilerOptions": {
...
"incremental": false,
"paths": { "#zorro/*": ["dist/libs/*"] }
},
This made tsc work, but when running with node, I get an error:
Error: Cannot find module '#zorro/types'
Can't figure out what needs to be changed in order to properly resolve the path of the library for the compiled main.js file.
First of all, some facts:
Node.js requires that all local imports include the imported module's extension (e.g. import hello from './hello.js', not import hello from './hello').
TypeScript will compile imports with or without the .js extension, which means a missing .js extension is a runtime error.
TypeScript doesn't transform imports to add the .js extension or convert .ts to .js.
In my Node.js project, I want to make missing a missing .js extension be a build-time error using the import/extensions ESLint rule. However, when I enable this rule using the following configuration:
{
"root": true,
"env": {
"node": true
},
"parser": "#typescript-eslint/parser",
"plugins": [
"#typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:#typescript-eslint/eslint-recommended",
"plugin:#typescript-eslint/recommended"
],
"settings": {
"import/resolver": {
"typescript": {},
"node": {
"extensions": [".js"]
}
}
},
"rules": {
"import/extensions": ["error", "ignorePackages"]
}
}
running eslint gives me the following error:
/sandbox/src/index.ts
1:19 error Missing file extension "ts" for "./hello.js" import/extensions
Source files:
// index.ts
import hello from "./hello.js";
hello();
// hello.ts
export default function hello() {
console.log("Hello");
}
CodeSandbox link: https://codesandbox.io/s/elated-germain-13glp7
I fixed this with the following config:
{
"root": true,
"env": {
"node": true
},
"extends": [
"eslint:recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:#typescript-eslint/eslint-recommended",
"plugin:#typescript-eslint/recommended"
],
"rules": {
"import/extensions": ["error", "ignorePackages"],
"import/no-unresolved": "off"
}
}
The main thing is to disable the "import/no-unresolved" rule and remove "settings"."import/resolver"."node". ("import/no-unresolved" is redundant as unresolved imports are resolved at the compilation stage.) Other items removed here were already being added as a result of extending the #typescript-eslint plugins.
I found an eslint plugin that can fix missing .js extensions for imports in .ts files, instead of just showing an error:
https://github.com/AlexSergey/eslint-plugin-file-extension-in-import-ts
https://www.npmjs.com/package/eslint-plugin-file-extension-in-import-ts
Install:
npm i -D eslint-plugin-file-extension-in-import-ts
Add to .eslintrc file:
{
"plugins": [
"file-extension-in-import-ts"
],
"rules": {
"file-extension-in-import-ts/file-extension-in-import-ts": "error"
}
}
NOTE: I ran into an issue similar to https://github.com/import-js/eslint-plugin-import/issues/1292 when using this package, and it will incorrectly try to add .js extensions on these paths when fixing automatically.
You could try ts-add-js-extension package to append .js extension to the transpiled JavaScript files. After you install you can do
ts-add-js-extension add --dir={your-transpiled-outdir}
I have a Node.js project written in Typescript with the following dependency:
"dependencies": {
...
"#uniswap/smart-order-router": "^2.5.15",
From this library package I import some stuff in my project:
import { AlphaRouter, ... } from '#uniswap/smart-order-router'
And then use it like this:
const routeToRatioResponse: SwapToRatioResponse = await router.routeToRatio(
token0Balance,
token1Balance,
p,
{
ratioErrorTolerance: new Fraction(5, 100),
maxIterations: 1,
},
{
swapOptions: {
recipient: wallet.address,
slippageTolerance: new Percent(5, 100),
deadline: deadlineValue
},
addLiquidityOptions: {
recipient: wallet.address
}
}
)
I have a breakpoint set on that first line above, at the call to router.routeToRatio(). When using the VS Code debugger, execution stops correctly at that line. But then when I click 'Step Into', I do not step into this function at all but instead go to the line after this whole function call.
The library project is written in Typescript. The code is here: https://github.com/Uniswap/smart-order-router. Note that the tsconfig.json for it has inlineSourceMap as true here: https://github.com/Uniswap/smart-order-router/blob/main/tsconfig.json#L9.
I don't seem to have the TS source for the library project in my node_modules dir. When I Ctrl-click on the function name, VS Code takes me to ./node_modules/#uniswap/smart-order-router/build/main/src/routers/alpha-router/alpha-router.d.ts (which has no implementation code, only a class declaration), not to a file called alpha-router.ts. Digging around under node_modules I seem not to have that file.
This answered question mentions the library project should have the sourceRoot set in the tsconfig.json, which it does not. I do not own the library project though, so I can't change anything there.
(Edit 1) Here's my launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "foo",
"type": "node",
"program": "${workspaceFolder}/foo/src/index.ts",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"preLaunchTask": "tsc: build - foo/tsconfig.json",
"outFiles": [
"${workspaceFolder}/**/*.js"
],
"cwd": "${workspaceFolder}/foo"
}
]
}
(Edit 2): Per the comments so far, I now have the dependencies I'm interested in debugging installed (in the npm install sense) as local folders. package.json looks like this:
"dependencies": {
...
"#uniswap/smart-order-router": "file:../smart-order-router",
...
tsconfig.json has "allowJs" missing. I had to install some of the dependency's dependencies directly in my package.json. The code now builds with tsc without errors (without having to change any paths to imports in the TS sources), but now the debugger is completely broken.
The debugger stops at a breakpoint on the very first line of my index.ts and will step over lines ok for a bit but then execution stops here without any error: node_modules/antlr4ts/index.js
The only thing on the debug console in VSC is:
/home/e/.nvm/versions/node/v14.15.4/bin/node ./node_modules/antlr4ts/index.js
Im trying to get vscode debugger to work with an application generated with AWS Sam, but with TypeScript.
So before I added TypeScript, the debugger worked fine, I could reach the breakpoints without issue.
When I added TypeScript, I had to change to folder structure, by adding a src and dist folder, so currently my file structure is like this:
According to AWS documentation (page 58): https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/aws-tookit-vscode-ug.pdf
I think it has to do with the pathMappings in the launch.json file, but I can't seem to figure out what would the correct path. This is my current launch.json file:
{
"configurations": [
{
"type": "aws-sam",
"request": "direct-invoke",
"name": "puppeteer-pdfMerger:HelloWorldFunction",
"invokeTarget": {
"target": "template",
"templatePath": "puppeteer-pdfMerger/template.yaml",
"logicalId": "HelloWorldFunction"
},
"lambda": {
"runtime": "nodejs12.x",
"payload": {},
"environmentVariables": {},
"pathMappings": [{
"localRoot": "${workspaceFolder}/puppeteer-pdfMerger/hello-world/dist/HelloWorldFunction",
"remoteRoot": "/var/task/dist"
}]
}
}
}
I will note that when running this configuration the containerized Lambda runs fine, it's just the breakpoints are not working.
I managed to get the breakpoints to work in the end.
What ended up working for me was changing the Dockerfile to:
FROM public.ecr.aws/lambda/nodejs:12
COPY dist/*.js package.json ./
RUN npm install
# Command can be overwritten by providing a different command in the template directly.
CMD ["app.lambdaHandler"]
And having the launch.json config as follows:
{
"type": "aws-sam",
"request": "direct-invoke",
"name": "puppeteer-pdfMerger:PdfGeneratorAndMergerFunction TemplateTarget",
"invokeTarget": {
"target": "template",
"templatePath": "puppeteer-pdfMerger/template.yaml",
"logicalId": "PdfGeneratorAndMergerFunction"
},
"lambda": {
"runtime": "nodejs12.x",
"payload": {},
"environmentVariables": {},
"pathMappings": [
{
"localRoot": "${workspaceRoot}/puppeteer-pdfMerger/hello-world/dist",
"remoteRoot": "/var/task"
}
]
}
}
I have some qunit tests setup to test my code that extensively uses requirejs. I use Chutzpah to perform the test running within VS. Everything works fine if I run the tests in the browser but not from within VS only. It seems to be ignoring my require.config call. If I change my references in my files to not point to shims but directly to files, it will work, but that breaks other things within my code.
Does anyone have this working? If so, how? I have looked at their example code but it doesn't use require.config and shims.
Start from this tutorial.
To run a config, with shims, just add a reference to your config file in chutzpah.json. Example below, slightly simplified for readability.
The chutzpah.json file
{
"Framework": "qunit",
"TestHarnessReferenceMode": "AMD",
"TestHarnessLocationMode": "SettingsFileAdjacent",
"References": [
{ "Path": "../Scripts/Components/RequireJS/require.js" },
{ "Path": "config.js" }
]
}
The config.js file
require.config({
"paths": {
"jquery": "../Scripts/jquery-2.1.4",
"jquery-linq": "../Scripts/jquery.linq",
"signalr": "../Scripts/jquery.signalR-2.2.0",
"signalrhubs": "../Scripts/mock-signalr-hubs",
"knockout": "../Scripts/knockout-3.3.0",
"constants": "../Scripts/constants",
"HomeVm": "Source/HomeVm"
},
"shim": {
"jquery.linq": {
"deps": ["jquery"]
},
"bootstrap": {
"deps": ["jquery"]
},
"signalr": {
"deps": ["jquery"]
}
}
});