Open isamert opened 2 years ago
Thanks for raising an issue!
2 things:
require
./app.module
which will probs happen even if it wasn't in TSIf that's the case, it may be nice to have a section describing under what circumstances skerrick works to the README. Good idea. Although, I'll really try to support as many things as I can :)
I'll replicate this later and attempt to fix it. Is it possible to create a non-Typescript NestJS project?
PS: Whoops, I forgot to document evalImports
Ok, I've confirmed that this issue's because of Typescript not being supported (yet - next on the roadmap though :D)
Although I did run skerrick on the dist
folder. Runs fine but when I update/eval nest controller/module code, it doesn't update the endpoint (e.g. I changed return Hello World
-> return Hello World!!!!
but doesn't take into effect). I'll investigate further.
This is a really good edge case :). I'm determined to get it working
I'll replicate this later and attempt to fix it. Is it possible to create a non-Typescript NestJS project?
AFAIK, yes. But I guess nest CLI tool does not bootstrap one for you, it's probably easier to use dist/
folder for testing as you did.
Ok, I've confirmed that this issue's because of Typescript not being supported (yet - next on the roadmap though :D)
Good to know! Quite exciting. I have some simple snippets that uses tree-sitter which I use for selecting typescript expressions automatically to send to REPL (like eval-last-sexp but for typescript and does some assumptions about what you are trying to evaluate), maybe we can incorporate those into skerrick.el or I can turn them into a package that works with skerrick.el. I believe the snippets can be easily adopted for JS too.
Although I did run skerrick on the dist folder. Runs fine but when I update/eval nest controller/module code, it doesn't update the endpoint (e.g. I changed return Hello World -> return Hello World!!!! but doesn't take into effect). I'll investigate further.
Can you give some workflow related tips regarding to skerrick? Like, lets say that I have changed a function inside a class, I guess I need to re-evaluate whole module or whole class to reflect the changes, right? As far as I understand, skerrick replaces the top-level definitions by it's name, inside the given module. ...and what about module systems, which ones does skerrick support or does it work independently of the module system somehow?
This is a really good edge case :). I'm determined to get it working
Thanks for investigating this issue in detail!
Re: snippets Sweet as! Feel free to suggest ways to incorporate those snippets. It'd be nice to have CIDER-like niceties for skerrick
Re: workflow Yeah, you'll have to evaluate the whole class at least.
As far as I understand, skerrick replaces the top-level definitions by it's name, inside the given module Yep and what about module systems, which ones does skerrick support or does it work independently of the module system somehow?
I'm planning to support both ES and commonjs modules (I've got the basic stuff working I believe - import
, export
(defaults, ns, members) and the cjs equivalents.
For cjs, I've got a few things I need to finish up (see https://github.com/anonimitoraf/skerrick/blob/main/notes.org).
Also check out the tests I've got https://github.com/anonimitoraf/skerrick/tree/main/server/test/evaluate.
As for the module system implementation - they're somewhat combined. The current implementation just simply tracks the values within each namespace/modules, regardless of how it's exported/imported.
I wasn't aware of that notes.org
file, will be tracking the updates from there. Also thanks for pointing me to the tests.
I understand the cause btw. Seems to only happen for commonjs exports/requires. The exported value gets cached as a namespace value (rather than just as an export) and doesn't get updated (even if you re-eval the export).
The problem with commonjs requires is the fact that babel
doesn't have a dedicated ParseTree node for it (compared to ES imports which do) so I'll have to find a way to detect a commonjs require and intercept it accordingly
Ok, so my plan of attack for this is:
So far, the most promising babel plugin for commonjs -> ES module transformation is https://gitlab.com/anonimitoraf/babel-plugin-transform-commonjs-es2015-modules but it seems to fail in a few cases like:
const binding = require('node-gyp-build')(__dirname)
where the RHS isn't a simple require('this')
so I might extend it/fix it up
For requires
, so far, these cases seem to fail
Really cool project, I really wanted something like this for quite a while. But I'm having issues while starting it.
Here is an example setup:
This gives you an working base NestJS project. Then I tried to run skerrick server, like this:
Here is the output I got:
Click to expand!
``` --- Port: 4321 --- Entry point /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts --- Eval imports? false code transformed: "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NestFactory = exports.APP_PIPE = exports.APP_INTERCEPTOR = exports.APP_GUARD = exports.APP_FILTER = void 0; const tslib_1 = require("tslib"); /* * Nest @core * Copyright(c) 2017 - 2021 Kamil Mysliwiec * https://nestjs.com * MIT Licensed */ registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "tslib_1", tslib_1); require("reflect-metadata"); tslib_1.__exportStar(require("./adapters"), exports); tslib_1.__exportStar(require("./application-config"), exports); var constants_1 = require("./constants"); registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "constants_1", constants_1); Object.defineProperty(exports, "APP_FILTER", { enumerable: true, get: function () { return constants_1.APP_FILTER; } }); Object.defineProperty(exports, "APP_GUARD", { enumerable: true, get: function () { return constants_1.APP_GUARD; } }); Object.defineProperty(exports, "APP_INTERCEPTOR", { enumerable: true, get: function () { return constants_1.APP_INTERCEPTOR; } }); Object.defineProperty(exports, "APP_PIPE", { enumerable: true, get: function () { return constants_1.APP_PIPE; } }); tslib_1.__exportStar(require("./discovery"), exports); tslib_1.__exportStar(require("./exceptions"), exports); tslib_1.__exportStar(require("./helpers"), exports); tslib_1.__exportStar(require("./injector"), exports); tslib_1.__exportStar(require("./metadata-scanner"), exports); tslib_1.__exportStar(require("./middleware"), exports); tslib_1.__exportStar(require("./nest-application"), exports); tslib_1.__exportStar(require("./nest-application-context"), exports); var nest_factory_1 = require("./nest-factory"); registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "nest_factory_1", nest_factory_1); Object.defineProperty(exports, "NestFactory", { enumerable: true, get: function () { return nest_factory_1.NestFactory; } }); tslib_1.__exportStar(require("./router"), exports); return tslib_1.__exportStar(require("./services"), exports); all imports Map(0) {} ns imports for scope {} ns for scope {} Failed to normalize import path: Error: Cannot find module './app.module' Require stack: - /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15) at Function.resolve (node:internal/modules/cjs/helpers:108:19) at normalizeImportPath (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:443:20) at PluginPass.enter (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:404:47) at newFn (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21) at NodePath._call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20) at NodePath.call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17) at NodePath.visit (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31) at TraversalContext.visitQueue (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16) at TraversalContext.visitMultiple (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17) { code: 'MODULE_NOT_FOUND', requireStack: [ '/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts' ] } /Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/core/lib/transformation/index.js:45 throw e; ^ Error: Cannot find module './app.module' Require stack: - /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15) at Function.resolve (node:internal/modules/cjs/helpers:108:19) at normalizeImportPath (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:443:20) at PluginPass.enter (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:404:47) at newFn (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21) at NodePath._call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20) at NodePath.call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17) at NodePath.visit (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31) at TraversalContext.visitQueue (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16) at TraversalContext.visitMultiple (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17) { code: 'MODULE_NOT_FOUND', requireStack: [ '/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts' ] } ```Then I realized there is an undocumented
evalImports
, I also tried setting it to true:Click to expand!
``` --- Port: 4321 --- Entry point /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts --- Eval imports? true code transformed: "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NestFactory = exports.APP_PIPE = exports.APP_INTERCEPTOR = exports.APP_GUARD = exports.APP_FILTER = void 0; const tslib_1 = require("tslib"); /* * Nest @core * Copyright(c) 2017 - 2021 Kamil Mysliwiec * https://nestjs.com * MIT Licensed */ registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "tslib_1", tslib_1); require("reflect-metadata"); tslib_1.__exportStar(require("./adapters"), exports); tslib_1.__exportStar(require("./application-config"), exports); var constants_1 = require("./constants"); registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "constants_1", constants_1); Object.defineProperty(exports, "APP_FILTER", { enumerable: true, get: function () { return constants_1.APP_FILTER; } }); Object.defineProperty(exports, "APP_GUARD", { enumerable: true, get: function () { return constants_1.APP_GUARD; } }); Object.defineProperty(exports, "APP_INTERCEPTOR", { enumerable: true, get: function () { return constants_1.APP_INTERCEPTOR; } }); Object.defineProperty(exports, "APP_PIPE", { enumerable: true, get: function () { return constants_1.APP_PIPE; } }); tslib_1.__exportStar(require("./discovery"), exports); tslib_1.__exportStar(require("./exceptions"), exports); tslib_1.__exportStar(require("./helpers"), exports); tslib_1.__exportStar(require("./injector"), exports); tslib_1.__exportStar(require("./metadata-scanner"), exports); tslib_1.__exportStar(require("./middleware"), exports); tslib_1.__exportStar(require("./nest-application"), exports); tslib_1.__exportStar(require("./nest-application-context"), exports); var nest_factory_1 = require("./nest-factory"); registerValue("/private/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/node_modules/@nestjs/core/index.js", "nest_factory_1", nest_factory_1); Object.defineProperty(exports, "NestFactory", { enumerable: true, get: function () { return nest_factory_1.NestFactory; } }); tslib_1.__exportStar(require("./router"), exports); return tslib_1.__exportStar(require("./services"), exports); all imports Map(0) {} ns imports for scope {} ns for scope {} Failed to normalize import path: Error: Cannot find module './app.module' Require stack: - /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15) at Function.resolve (node:internal/modules/cjs/helpers:108:19) at normalizeImportPath (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:443:20) at PluginPass.enter (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:404:47) at newFn (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21) at NodePath._call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20) at NodePath.call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17) at NodePath.visit (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31) at TraversalContext.visitQueue (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16) at TraversalContext.visitMultiple (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17) { code: 'MODULE_NOT_FOUND', requireStack: [ '/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts' ] } /Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/core/lib/transformation/index.js:45 throw e; ^ Error: Cannot find module './app.module' Require stack: - /var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15) at Function.resolve (node:internal/modules/cjs/helpers:108:19) at normalizeImportPath (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:443:20) at PluginPass.enter (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/dist/engine.js:404:47) at newFn (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/visitors.js:177:21) at NodePath._call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:53:20) at NodePath.call (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:40:17) at NodePath.visit (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/path/context.js:100:31) at TraversalContext.visitQueue (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:103:16) at TraversalContext.visitMultiple (/Users/isamert.gurbuz/.npm-packages/lib/node_modules/skerrick/node_modules/@babel/traverse/lib/context.js:72:17) { code: 'MODULE_NOT_FOUND', requireStack: [ '/var/folders/pn/_2wjbhjx5y51f0hdx1_r67hm0000gp/T/tmp.XCNl4St8NB/testproj/src/main.ts' ] } ```Maybe skerrick isn't supposed to work for projects like this? If that's the case, it may be nice to have a section describing under what circumstances skerrick works to the README.