davidje13 / neutrino-typescript

Transpiles TypeScript as part of the build process.
MIT License
8 stars 2 forks source link

Cannot generate definitions when using @neutrinojs/react-components #8

Closed realmorrisliu closed 4 years ago

realmorrisliu commented 4 years ago

Here is my config, but I can't find .d.ts in build directory

const typescript = require('neutrinojs-typescript')
const reactComponents = require('@neutrinojs/react-components')
const jest = require('@neutrinojs/jest')
const lessLoader = require('neutrino-middleware-less-loader')

module.exports = {
  options: {
    root: __dirname,
    mains: {
      index: {
        entry: 'index',
      },
    },
  },
  use: [
    typescript({
      tsconfig: {
        compilerOptions: {
          strict: true,
          allowJs: true,
          declaration: true,
          typeRoots: [
            'src/types', // custom types directory
            'node_modules/@types',
          ],
        },
      },
    }),
    reactComponents(),
    jest(),
    lessLoader(),
    (neutrino) => {
      neutrino.config.module.rule('wasm').
        test(/\.wasm$/).
        type('javascript/auto').
        include.
        add(/draco/).
        end().
        use('draco').
        loader('file-loader').
        options({})
    },
    (neutrino) => {
      neutrino.config.output.globalObject('this') // will prevent `window`
        .end().
        module.
        rule('worker').
        test(neutrino.regexFromExtensions(['worker.js'])).
        use('worker').
        loader(require.resolve('worker-loader')).
        options({
          // See: https://github.com/webpack-contrib/worker-loader#options
        })
    },
  ],
}
davidje13 commented 4 years ago

hmm, seems that react-components does some funky mains handling when in production mode (https://github.com/neutrinojs/neutrino/blob/master/packages/react-components/index.js#L43) - I'll see if there's a way to play nicely with it. It might be necessary to capture the mains config before it gets a chance to run (should be easy enough since the typescript plugin already has to be ordered first.

davidje13 commented 4 years ago

Found the problem; turns out that react-components replaces the mains option with its own values (by listing the contents of the components directory). The problem is that it puts the directories, not the files as the entry points (i.e. /foo/src/components/Example rather than /foo/src/components/Example/index). Seems to work fine for webpack, but TypeScript barfs.

I'll add something in to detect if the given entry point is a directory, and if so, append /index to the end, which should fix this.

davidje13 commented 4 years ago

I have put in a fix for this (released as version 1.1.6) but note that you may encounter further problems due to #6 - TypeScript doesn't natively support renaming/moving output relative to the source files.

Specifically, I see that if there is only one component, it will now generate build/index.d.ts, but if there is more than one, it will generate build/ComponentName/index.d.ts instead. The latter might be OK, so as long as you have multiple components you could be fine. Annoyingly there's no obvious programmatic indication of where it puts these files and they often contain relative paths to other files, so it's not a simple task to move them around manually.

There are a few relevant issues raised with TypeScript directly if you're interested:


Give the latest version a try (and test that the definitions it generates actually work for your use-case) and let me know if you still have problems.

realmorrisliu commented 4 years ago

Thanks for your work! It works great in my project!!