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

TypeScript transformer for React Refresh #19914

Closed
wants to merge 33 commits into from
Closed

TypeScript transformer for React Refresh #19914

wants to merge 33 commits into from

Conversation

Jack-Works
Copy link
Contributor

@Jack-Works Jack-Works commented Sep 27, 2020

Not merged. Please move to react-refresh-typescript (repo)

TypeScript transformer for React Refresh

Note: If you are using TypeScript (instead of Babel) as a transpiler, you will still need to use babel-loader to process your source code. Check out this sample project on how to set this up.

-- React Refresh Webpack Plugin

Now it's no longer the case! Here is the TypeScript version of the transformer.

Minimal requirement

  • TypeScript 4.0

Example (with ts-loader)

{
    test: /\.tsx?$/,
    loader: 'ts-loader',
    exclude: /node_modules/,
    options: {
        getCustomTransformers: () => ({
            before: [require('react-refresh/typescript')()]
        }),
    }
}

Example (with raw TypeScript transpileModule API)

import refresh from 'react-refresh/typescript';
const out = ts.transpileModule('const App = () => <Something />', {
    compilerOptions: {
        target: ts.ScriptTarget.ESNext,
        jsx: ts.JsxEmit.Preserve,
    },
    fileName: 'test.jsx',
    transformers: {before: [refresh(options)]},
}).outputText,

Options

refreshReg?: string

Same as the babel version

refreshSig?: string

Same as the babel version

emitFullSignatures?: boolean

Same as the babel version

@codesandbox-ci
Copy link

codesandbox-ci bot commented Sep 27, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 8448fe2:

Sandbox Source
React Configuration

@sizebot
Copy link

sizebot commented Sep 27, 2020

No significant bundle size changes to report.

Size changes (experimental)

Generated by 🚫 dangerJS against 8448fe2

@sizebot
Copy link

sizebot commented Sep 27, 2020

No significant bundle size changes to report.

Size changes (stable)

Generated by 🚫 dangerJS against 8448fe2

@gaearon
Copy link
Collaborator

gaearon commented Sep 27, 2020

Wow, thanks for the PR! What is your thinking on when one would go with this approach over compiling with Babel? Is there any data on how prevalent using TS directly as the compiler among people who use webpack? I want to understand how valuable this is given that it's extra maintenance burden and keeping them in sync might be a bit difficult.

@Jack-Works
Copy link
Contributor Author

Hi! At least I'm using the TypeScript directly without babel.

You can see in the react refresh webpack plugin repository, you can also find others are want to use react refresh without babel.

About maintenance, feel free to CC me if it needs some change. Although I can't promise, I will try to maintain this in the future.

@samcooke98
Copy link

I wanted to chime in to +1 to the use-case of typescript without babel.

At least where I work, we don't use babel to transform anymore. We used to do typescript -> babel in the past due to some build issues, but since resolving those issues and removing babel, our build speeds have increased.

We're unlikely to add babel back for a single transform, so a typescript transformer would be really nice, and (hopefully) keep our build times lower. This would also help reduce the overheard of trying to introduce react-refresh IE: it's easier to convince our infra engineers that we should include a transformer, vs introduce back babel, and use it's transformer.

@Jack-Works
Copy link
Contributor Author

@gaearon hi any progress on reviewing this?

@Jack-Works
Copy link
Contributor Author

If you can't wait for this PR, I have released a package for temp use. http://npmjs.com/package/react-refresh-typescript

cc who might be interested in this: @samcooke98 @petermikitsh @dai-shi @EmilNordling @webmail @Y0ba

@alii
Copy link

alii commented Oct 14, 2020

Brilliant work, thank you!

@alii
Copy link

alii commented Oct 24, 2020

Hi @Jack-Works, do you know if there is a type definition for your react-refresh-typescript on npm? Currently, my webpack config looks like this:

import Webpack from 'webpack';
import path from 'path';

const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const HTMLWebpackPlugin = require('html-webpack-plugin');

// @ts-ignore
import RRT = require('react-refresh-typescript');

const isDev = process.env.NODE_ENV !== 'production';

const config: Webpack.Configuration = {
  mode: isDev ? 'development' : 'production',
  entry: './src/index.tsx',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
          getCustomTransformers: () => ({
            before: [RRT.default()],
          }),
        },
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: './',
  },
  plugins: [
    new HTMLWebpackPlugin({
      template: './public/index.html',
      filename: 'index.html',
      minify: 'auto',
    }),
    isDev && new ReactRefreshWebpackPlugin(),
    isDev && new Webpack.HotModuleReplacementPlugin(),
  ].filter(Boolean),
  devServer: isDev
    ? {
        hot: true,
        port: 3000,
        open: 'http://localhost:3000',
        host: '0.0.0.0',
      }
    : undefined,
};

export default config;

however it doesn't seem to be working, and if I remove the // @ts-ignore, I'm told

[webpack-cli] webpack.config.ts:7:22 - error TS7016: Could not find a declaration file for module 'react-refresh-typescript'.```

@Jack-Works
Copy link
Contributor Author

Yeah, that's for temporary use until this PR gets merged. I'll provide a type definition later. @alii

@alii
Copy link

alii commented Oct 24, 2020

@Jack-Works that's brilliant, thank you. For the time being, I'll write my config file in js. Thanks again.

@Jack-Works
Copy link
Contributor Author

@alii hi please try 1.0.3, and I also add .d.ts for this PR

@alii
Copy link

alii commented Oct 24, 2020

@Jack-Works great work, thanks. I will test this out now.

@alii
Copy link

alii commented Oct 24, 2020

Edit 3: Using useState seems to produce the previous error (see this comment's edit history for webpack config and code). Will investigate further. It might be that I need to switch React versions.

@Jack-Works
Copy link
Contributor Author

Seems like no progress. Please move to react-refresh-typescript (repo). I'm maintaining the tool there.

@gaearon
Copy link
Collaborator

gaearon commented Nov 8, 2020

Hey @Jack-Works, sorry for no response, I just saw the updates.

Reading over this, I do feel like it makes more sense for this to live in an external repo first since we're not TS experts and you would have a more focused workspace there with isolated issues etc. I think it would also make sense to change the repo title to match the package name so that it's easier to find, since right now it looks ambiguous with the official package.

I'd be happy to take a PR linking from our package's README to yours (for TS users).

We could also make react-refresh/typescript re-export your package. However, the concern there is with the commitment to support. E.g. if you don't have time to work on this project in the future (which is totally ok and happens), it would become a problem for us because we'd need to pick it up. That's the main hesitation with making it an official entry point. If there is a bigger maintainer community behind that project (2-3 volunteers) I would feel better about this.

@Jack-Works
Copy link
Contributor Author

I think it would also make sense to change the repo title to match the package name so that it's easier to find, since right now it looks ambiguous with the official package.

Yeah, that repo is a monorepo, I may develop SWC plugins for React Refresh later, so it's not called "react-refresh-typescript".

We could also make react-refresh/typescript re-export your package. However, the concern there is with the commitment to support. E.g. if you don't have time to work on this project in the future (which is totally ok and happens), it would become a problem for us because we'd need to pick it up.

I understand your concerns. No need to re-export my package, a link that marked as non-official / community will be good enough.

I'd like to receive updates if the transform rule is changed or new test cases are adopted to make the TypeScript version up to date with the babel version.

@wind4gis
Copy link

how to config with babel-loader instead of ts-loader

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

Successfully merging this pull request may close these issues.

7 participants