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

Support custom AST transformers #28

Closed
kastermester opened this issue Mar 2, 2018 · 11 comments
Closed

Support custom AST transformers #28

kastermester opened this issue Mar 2, 2018 · 11 comments

Comments

@kastermester
Copy link

Nice project!

I really like the looks of this, and have, very briefly, tried it out. Well done!

I am looking into creating some personal toy projects in the future using Parcel (have only just tried it out so far, but have been very happy with the result), however much of my work revolves around using facebook/relay. To be able to use that properly I'd want to inject a custom AST transformer, which I see is on the TODO.

I wanted to know if you have any plans for how to implement this, I'd love to give a hand with it, but I'm not quite sure how it should be configured (given that tsconfig.json AFAIK does not support configuring it).

@fathyb
Copy link
Owner

fathyb commented Mar 2, 2018

I made parcel-bundler#734 to support transformers and I don't think it's going to be merged in the core.

If the proposal looks good to you or if you have any recommendation on how we should define them let me know.

@fathyb fathyb added this to To Do in Plugin via automation Mar 2, 2018
@kastermester
Copy link
Author

That looks good to me!

I'll be the first to admit I don't have much of an overview of the architecture of Parcel wrt. plugins. Is this something that has to be added to the parcel-bundler repo, or can it be implemented in this plugin repo?

fathyb added a commit that referenced this issue Mar 2, 2018
@fathyb
Copy link
Owner

fathyb commented Mar 2, 2018

I've just published parcel-plugin-typescript@0.8.0-next.0 with transformers support. I'm currently using it and it seems to work fine! 🎉

You can configure the transformers in the tsconfig.json like this (use the Parcel PR for the reference on how the export the factories) :

{
  "compilerOptions": { /* ... */ },
  "parcel-plugin-typescript": {
    "transformers": "./your-transformers-factory"
  }
}

@fathyb fathyb added this to the Next iteration milestone Mar 2, 2018
@kastermester
Copy link
Author

That was quick! I will try it out soon enough and report back if it works for me! :)

@zerkalica
Copy link

May be make compatible your transformer api with rollup-plugin-typescript2 transformers?

export interface ICustomTransformer
{
	before?: tsTypes.TransformerFactory<tsTypes.SourceFile>;
	after?: tsTypes.TransformerFactory<tsTypes.SourceFile>;
}

export type TransformerFactoryCreator = (ls: tsTypes.LanguageService) => tsTypes.CustomTransformers | ICustomTransformer;
...
transformers: TransformerFactoryCreator[];

Passing tsTypes.LanguageService to plugin more common than CompilerOptions and allow to inject language service plugins, not only transforms.

@fathyb
Copy link
Owner

fathyb commented May 7, 2018

@zerkalica Thanks for the link, didn't know rpts2 supports transformers. The language service is only available in watch mode and we don't use it to generate files, in build mode we use the TypeScript compiler as it is faster. The language service has been made for IDEs and not build tools. IIRC the TypeScript team recommend against using it for non-IDE purposes.

I'm only using it because I'm too lazy to build something custom (although TypeScript recently added something for it) and I suspect other build tools to do the same for the same reasons.

I think ts.TypeChecker and ts.CompilerOptions is more than enough for 99% transformers.
What do you think of adding a property type with possibles values like webpack/ts-loader, webpack/awesome-typescript-loader, and rollup? I hate fragmentations but without any real standard it's hard to define.

"parcel-plugin-typescript": {
  "transformers": {
    "type": "rollup",
    "path": "./your-transformers-factory"
  }
}

@zerkalica
Copy link

I think, you can remove transformer chain and use ttypescript wrapper. Just require ttypescript in your code or provide option to require it instead of typescript.
We prepare create PR cevek/ttypescript#11. One chain for all transformer formats. Webpack and rollup loaders/plugins can be configured with ttypescript.

@fathyb
Copy link
Owner

fathyb commented May 11, 2018

@zerkalica while I'm not sure if we can directly integrate ttypescript (tons of reasons that make Parcel special 🙃) I really like the format! I'll work on implementing this.

@zerkalica
Copy link

Why? You don't need custom https://github.com/fathyb/parcel-plugin-typescript/blob/develop/src/backend/transpiler.ts

Just import * as ts from 'ttypescript'

@fathyb
Copy link
Owner

fathyb commented May 11, 2018

That's just one of the tons of calls to TypeScript, in fact when building we don't use even use this file and we internally use transformers (PathTransform and the Parcel internal asset transformation on next).

Also I'm preparing pure AST transformations on the next branch (c511bd6) (totally bypasses Babel), this adds additional complexity and import calls to TypeScript, and we need the exact same instance everywhere. It's just way more simple to implement it internally, other bundlers plugins can afford it because they don't have to deal with multi-processing (Parcel is currently the only multi-core bundler) and context dependent configuration.

@zerkalica
Copy link

You can use PathTransform with ttypescript:

compilerOptions: {
  plugins: [
    { transform: './PathTransform' }
  ]
}

Or use already builded plugin, like ts-transform-paths

ttypescript is drop-in replacement for all exported typescript modules, including tsc, tsserver, etc.

It just patches createProgram and reexports typescript lib.

var ts = require("typescript/lib/typescript");
var patchCreateProgram_1 = require("./patchCreateProgram");
patchCreateProgram_1.patchCreateProgram(ts);
module.exports = ts;

typescript is the peer dependency, so you can use any version of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Plugin
  
Done
Development

No branches or pull requests

3 participants