Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node JS API #372

Closed
Subash opened this issue Aug 6, 2014 · 53 comments
Closed

Node JS API #372

Subash opened this issue Aug 6, 2014 · 53 comments
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@Subash
Copy link

Subash commented Aug 6, 2014

Is there an api that can be require ed from node to compile file. eg

var ts = require('typescript');
ts.compile(filePath, {options}, function(err, js) {
 //etc
})
@eiszfuchs
Copy link

Would love that, too!
Previously on: http://typescript.codeplex.com/workitem/97

@biiiipy
Copy link

biiiipy commented Aug 6, 2014

+1
Maybe this could be added in the new TS compiler that's coming soon?

@basarat
Copy link
Contributor

basarat commented Aug 6, 2014

Is there an api that can be require ed from node to compile file

The typescript compiler doesn't use external modules so no to "require"ed by default. But otherwise it's not hard. See : https://www.npmjs.org/package/typestring (which uses typescript-api which is basically same as https://github.com/basarat/typescript-services#getting-the-language-service to see how you can build it from the compiler src)

@Subash
Copy link
Author

Subash commented Aug 6, 2014

I know that but editing a module is not my option. There should be an export because this is a node module.

@basarat
Copy link
Contributor

basarat commented Aug 6, 2014

But otherwise it's not hard

I meant that you can require('typestring') today if you want to use string-in string-out compilation https://www.npmjs.org/package/typestring

I was additionally trying to explain explain how typestring works.

@RyanCavanaugh
Copy link
Member

TypeScript is intentionally not an external module so that it can be used in places where there isn't a module loader (e.g. tsc.exe). There are lots of solutions available for using vanilla JS code in node.

@Subash
Copy link
Author

Subash commented Aug 6, 2014

@RyanCavanaugh, Can i ask why is that ? You can just export module if the environment is node.
It made me sad that you closed this issue without a proper explanation.

@RyanCavanaugh
Copy link
Member

Please clarify which part you'd like a "why" for.

What are you proposing, specifically?

@basarat
Copy link
Contributor

basarat commented Aug 7, 2014

Can i ask why is that

@Subash This should help clarify : #309 (comment)

@Bartvds
Copy link

Bartvds commented Aug 7, 2014

Why not both?

It' is pretty trivial to check the code is running as main file or is required as a module. Many modules on npm do it.

@basarat
Copy link
Contributor

basarat commented Aug 7, 2014

Why not both?

👍

Probably the team wants the generated compiler to be "raw compiler output". So would need a similar feature in the emitter.

@Bartvds
Copy link

Bartvds commented Aug 7, 2014

It's just this little snippet:

if (require.main === module) {
    // handle process.argv
} else {
    // be a module, export stuff
}

Seems doable right?

@basarat
Copy link
Contributor

basarat commented Aug 7, 2014

Seems doable right?

indeed. That wouldn't need any emitter change either. Here :

https://github.com/Microsoft/TypeScript/blob/9e6cacb70163081c10198e9a0ea55b5921cffaee/src/compiler/tc.ts#L450

if (require && module && (require.main === module)) {
    // handle process.argv
    ts.executeCommandLine(sys.args);
} else {
    // be a module, export stuff
    module.exports = ts;
}

Also would need an update of package.json for npm require('typescript')

@RyanCavanaugh would such a PR be welcome?

@RyanCavanaugh
Copy link
Member

Seems reasonable.

@basarat
Copy link
Contributor

basarat commented Aug 8, 2014

if (require && module && (require.main === module)) {
    // handle process.argv
    ts.executeCommandLine(sys.args);
} else {
    // be a module, export stuff
    module.exports = ts;
}

Will not work if its not started from nodejs (e.g. cscript). Will investigate a better option

@Bartvds
Copy link

Bartvds commented Aug 8, 2014

Wrap it in a node detection if/else? Check if require exists etc. IIRC there exists code for it in the IO part of the compiler.

@ivogabe
Copy link
Contributor

ivogabe commented Aug 8, 2014

Wouldn't it be better to add this to services.js?

if (typeof module !== "undefined") {
  module.exports = ts;
}

Then we have one file (tc.js) that is only for cli usage and a file (services.js) that can be used in other projects.

@basarat
Copy link
Contributor

basarat commented Aug 8, 2014

Wouldn't it be better to add this to services.js

@ivogabe good point. I think that's the way to go. You get access to the service classes as well 👍

@RReverser
Copy link
Contributor

Services gonna be removed as far as I understand from #254.

@basarat
Copy link
Contributor

basarat commented Aug 9, 2014

Services gonna be removed as far as I understand from

@RReverser No. Services were removed and are in the process of being rewritten

@RReverser
Copy link
Contributor

@basarat Right now they don't seem to be removed - jake local builds them normally along with compiler.

However, I don't really understand why do we need duplicated code in both services and compiler, that is synchronized only by using this SyntaxGenerator thing.

@basarat
Copy link
Contributor

basarat commented Aug 9, 2014

I don't really understand why do we need duplicated code in both services and compiler,

@RReverser There is no duplicated code in the new workflow. From current JakeFile:

var compilerSources = [
    "core.ts",
    "sys.ts",
    "types.ts",
    "scanner.ts",
    "parser.ts",
    "binder.ts",
    "checker.ts",
    "emitter.ts",
    "commandLineParser.ts",
    "tsc.ts",
    "diagnosticInformationMap.generated.ts"
].map(function (f) {
    return path.join(compilerDirectory, f);
});

var servicesSources = [
    "core.ts",
    "sys.ts",
    "types.ts",
    "scanner.ts",
    "parser.ts",
    "binder.ts",
    "checker.ts",
    "emitter.ts"
].map(function (f) {
    return path.join(compilerDirectory, f);
}).concat([
    "services.ts",
    "shims.ts",
].map(function (f) {
    return path.join(servicesDirectory, f);
}));

The compiler source is used in the services

So the only code that matters for new languageService is in services.ts

@jbondc
Copy link
Contributor

jbondc commented Sep 26, 2014

Agree with exposing the compiler, a simple approach could be to add:
package.json
"main" : "./bin/tsc_node.js",

Which just appends:
module.exports = ts;

Patch here:
https://github.com/jbondc/TypeScript/compare/issue-372-npm

Could be constrained to a more specific api, thoughts?

@Arnavion
Copy link
Contributor

@jbondc If I'm reading it right, your generated tsc_node.js will still try to parse the commandline and run the compiler when require'd, so it's not suitable for use in a script that does require("tsc_node.js") intending to use the TS compiler API.

I think what you want to do is have tsc.js as-is, with ts.executeCommandLine(sys.args); at the end of the file, and tsc_node.js as the same but with that line replaced by module.exports = ts;

Alternatively, do that replacement in tsc.js itself, don't create a new file tsc_node.js, and add ts.executeCommandLine(sys.args); to bin/tsc (where ts is the result of the require(...))

@jbondc
Copy link
Contributor

jbondc commented Sep 27, 2014

@Arnavion Good catch, ya would need to remove ts.executeCommandLine(sys.args) from tsc.js and put it in bin/tsc

@mhegazy My preference would be require("typescript") (compiler only) and require("typescriptServices") (more advanced, analyzing tokens,...) or it could be require("tsc") (compiler only) and require("typescript") (full bundle more advanced, analyzing tokens,...)

@RReverser
Copy link
Contributor

@jbondc @Arnavion Why creating separate bin/tsc at all? Just add !module.parent condition to the same if (...) ts.executeCommandLine(sys.args) in the end, so it will be executed only when module is not required but executed from command-line.

@jbondc
Copy link
Contributor

jbondc commented Sep 28, 2014

Updated the patch, kept 'bin/tsc.js' intact not to break any existing behavior.

Basically just removed that line in the build process and exporting this api:

https://github.com/jbondc/TypeScript/blob/e43b47277cc8c6f3c972ebe2600bfcc36d5da12b/src/api/typescript_node.js

@bashor
Copy link

bashor commented Oct 8, 2014

Any news, ETA? Will it be part of M1.3?

@mhegazy
Copy link
Contributor

mhegazy commented Oct 8, 2014

Still working on the LS. we need to delete the old tree first then we can publish an API.

@bashor
Copy link

bashor commented Oct 21, 2014

Any news? Could you provide related issues?

@akfish
Copy link

akfish commented Dec 2, 2014

I noticed that v1.3 was released a month ago. Were compiler and language service APIs included in that release?

@Arnavion
Copy link
Contributor

Arnavion commented Dec 2, 2014

@akfish According to https://github.com/Microsoft/TypeScript/wiki/Roadmap it is going to be in 1.4

@akfish
Copy link

akfish commented Dec 3, 2014

@Arnavion Thanks for the information.

@mhegazy mhegazy added Bug A bug in TypeScript and removed Revisit An issue worth coming back to Suggestion An idea for TypeScript labels Dec 11, 2014
@mhegazy mhegazy added this to the TypeScript 1.4 milestone Dec 11, 2014
@mhegazy mhegazy added the Suggestion An idea for TypeScript label Dec 11, 2014
@DanielRosenwasser DanielRosenwasser added the Fixed A PR has been merged for this issue label Dec 12, 2014
@DanielRosenwasser
Copy link
Member

Hi guys, @mhegazy and I have taken some initial steps on this in #1417. You'll find a new file produced by the build called typescript.d.ts in built/local. You can grab the bits from both master and release-1.4 as you please.

You can sample it by checking out the branch of your choice and running

  1. jake LKG
  2. npm install -g, and then
  3. npm link typescript from wherever you npm project resides (or from your home directory if you want to be able to require("typescript") from a node prompt).

With that and our .d.ts file, you should be able to hit the ground running by making a new file with something like the following:

/// <reference path="your/typings/directory/typescript.d.ts" />

var ts = import("typescript");

While it's not yet set in stone, please give it a try and let us know what you think! We definitely want a good experience for anyone consuming this API.

From here on, I think it might be appropriate to open a new issue for anything related to this API.

Thanks!

@bashor
Copy link

bashor commented Dec 19, 2014

@DanielRosenwasser @mhegazy could you please provide the ability to get SyntaxTree from LanguageService?

@DanielRosenwasser
Copy link
Member

SyntaxTree is no longer supported, SyntaxKind is our new model. I believe we only have SyntaxTree around to ensure that we are reaching parity with it with respect to incremental parsing.

@csnover
Copy link
Contributor

csnover commented Jan 12, 2015

Just to verify, is there any LanguageServiceHost implementation other than LanguageServiceShimHostAdapter?

@Arnavion
Copy link
Contributor

@csnover You're meant to give your own implementation of LanguageServiceHost to ts.createLanguageService() , since its implementation (get filenames, get contents of files, etc.) will depend on the hosting application. If you want an example, see class TypeScriptLS in src/harness/harnessLanguageService.ts (that implements the shim interface) and how it's converted via the Adapter to the new interface.

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests