TypeStrong / tsify

Browserify plugin for compiling TypeScript
344 stars 75 forks source link

Module aliasing not supported #255

Closed ondratra closed 5 years ago

ondratra commented 5 years ago

Hello, I need to rename all react requires and imports to preact. But because aliasify can't be used with tsify as stated here + browserify doesn't support ES import syntax in it's b.require('x', {expose: 'y'}) + tsify doesn't support Typescript paths directive as stated here; I see now way of achieving this.

I propose creating of new tsify option that accepts simple callback((name: string) => string) that can be used to change required package name before loading that dependency.

Could there be a new feature in tsify allowing such aliasing of packages? Or is there any other way how to achieve this?

I've wrote some more relevant info to preact's issue https://github.com/preactjs/preact/issues/1771 .

cartant commented 5 years ago

I'd suggest using TypeScript's paths option and putting another plugin after tsify to modify the paths in the emitted files. IIRC, TypeScript uses the paths option when it reads/resolves files, but writes files containing the original, unchanged import locations. This was - and remains - the reason for my not wanting to include path-modifying behaviours in tsify.

The second comment you referenced - this one - mentions pathmodify. With it - or some similar plugin - you ought to be able to modify the paths within the files emitted from tsify.

For the reasons mentioned in the first comment you mentioned, I very much doubt that a 'simple callback' could be used to do what you want.

ondratra commented 5 years ago

I had negative results with couple of other plugins like awesome-aliasify but pathmodify was a way to go! Thank you.

For anyone having the same problem this is how you get it done:

Minimum build:

const browserify = require('browserify')
const tsify = require('tsify')
const pathmodify = require('pathmodify')
const fs = require('fs')

const tsConfig = JSON.parse(fs.readFileSync(__dirname + '/tsconfig.json'))

// assume this file depend on preact & some react components
const sourcePath = __dirname + '/src/index.tsx'

browserify({entries: [sourcePath]})
    .plugin(pathmodify, {
        mods: [
            pathmodify.mod.id('react', 'preact/compat'), // use preact-compat for preact v8
            pathmodify.mod.id('react-dom', 'preact/compat') // use preact-compat for preact v8
        ]
    })
    .plugin(tsify, tsConfig.compilerOptions)
    .bundle()
    .pipe(fs.createWriteStream(__dirname + '/dist/bundle.js'))

Content of tsconfig.ts

{
    "compilerOptions": {
        "target": "es5",
        "moduleResolution": "node",
        "lib": ["es2017", "dom"],
        "jsx": "react",
        "jsxFactory": "h"
    }
}