pmmmwh / react-refresh-webpack-plugin

A Webpack plugin to enable "Fast Refresh" (also previously known as Hot Reloading) for React components.
MIT License
3.14k stars 194 forks source link

Support typescript loader ? #34

Closed KurganskySergey closed 4 years ago

KurganskySergey commented 4 years ago

Does this plugin force me to use babel ? I'm developing react project while using only typescript loader in webpack. Can i use your awesome tool for my project or maybe you have plans to support other loaders ?

TrySound commented 4 years ago

This is babel specific tool. You can add babel after typescript or use only babel to transpile your code. https://github.com/facebook/react/tree/master/packages/react-refresh/src

react-refresh-webpack-plugin does nothing with babel. It's additional webpack specific integration.

KurganskySergey commented 4 years ago

looks like i can do it this way:

module: {
    rules: [
        {
            test: /\.tsx?$/,
            exclude: /(node_modules|bower_components)/,
            use: {
                loader: 'babel-loader',                 
            },
        },
        // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
        {
            test: /\.tsx?$/,
            loader: 'awesome-typescript-loader',
        }
    ],
},

no .babelrc no other configs for babel.

KurganskySergey commented 4 years ago

If i change the order of rules it doesn't work i think rules are applied in reverse order to files

markovicdenis commented 4 years ago

You could use babel to compile typescript and use tsc --noEmit to have the error reports. Or you could use tsc to convert typescript to JS and use the compiled JS as input paths in webpack (which I am currently doing now, this also allows you to skip some babel plugins like class-properties, decorators etc, since the tsc handles those).

KurganskySergey commented 4 years ago

I use awsome-typescript-loader and i belive it's more convenient then both usecases you've described

atjeff commented 4 years ago

@KurganskySergey Would you mind sharing more of your webpack / tsconfig? I am having trouble setting this up

KurganskySergey commented 4 years ago
const path = require('path')
const { CheckerPlugin } = require('awesome-typescript-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const Dotenv = require('dotenv-webpack')
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
// ... your other imports

// You can tie this to whatever mechanisms you are using to detect a development environment.
// For example, as shown here, is to tie that to `NODE_ENV` -
// Then if you run `NODE_ENV=production webpack`, the constant will be set to false.
const isDevelopment = process.env.NODE_ENV !== 'production'

module.exports = {
    mode: isDevelopment ? 'development' : 'production',
    devtool: 'source-map',
    entry: './index.tsx',
    output: {
        path: path.resolve(__dirname, '.', 'dist'),
        filename: 'bundle.js',
        publicPath: '/',
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        // ... other options
                        // DO NOT apply the plugin in production mode!
                        plugins: [
                            require.resolve('react-refresh/babel'),
                            // [
                            //  '@babel/plugin-transform-runtime',
                            //  {
                            //      regenerator: true,
                            //  },
                            // ],
                        ],
                    },
                },
            },
            // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
            {
                test: /\.tsx?$/,
                loader: 'awesome-typescript-loader',
            },
            {
                test: /\.css$/i,
                use: ['style-loader', 'css-loader'],
            },
        ],
    },
    resolve: {
        extensions: ['.js', 'jsx', '.ts', '.tsx', '.json'],
    },
    plugins: [
        new Dotenv(),
        new HtmlWebpackPlugin({
            template: './public/index.html',
        }),
        new CheckerPlugin(),
        // ... other plugins
        // You could also keep the plugin in your production config,
        // It will simply do nothing.
        isDevelopment && new ReactRefreshWebpackPlugin(),
    ].filter(Boolean),
    resolveLoader: {
        modules: ['node_modules'],
    },
    devServer: {
        historyApiFallback: true,
        contentBase: './dist',
        hot: false,
    },
}
{
    "compilerOptions": {
        /* Basic Options */
        // "incremental": true,                   /* Enable incremental compilation */
        "target": "es2018",
        /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
        "module": "commonjs",
        /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
        "lib": ["es6", "dom"],
        /* Specify library files to be included in the compilation. */
        "allowJs": true,
        /* Allow javascript files to be compiled. */
        "checkJs": true,

        "skipLibCheck": true,
        /* Report errors in .js files. */
        "jsx": "react",
        /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
        // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
        // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
        "sourceMap": true,
        /* Generates corresponding '.map' file. */
        // "outFile": "./",                       /* Concatenate and emit output to single file. */
        // "outDir": "./",                        /* Redirect output structure to the directory. */
        // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
        // "composite": true,                     /* Enable project compilation */
        // "tsBuildInfoFile": "./",               /* Specify file to store incremental compilation information */
        // "removeComments": true,                /* Do not emit comments to output. */
        "noEmit": true,
        /* Do not emit outputs. */
        // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
        // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
        "isolatedModules": true,
        /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

        /* Strict Type-Checking Options */
        "strict": true,
        /* Enable all strict type-checking options. */
        "noImplicitAny": true,
        /* Raise error on expressions and declarations with an implied 'any' type. */
        "strictNullChecks": true,
        /* Enable strict null checks. */
        "strictFunctionTypes": true,
        /* Enable strict checking of function types. */
        // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
        "strictPropertyInitialization": false,
        /* Enable strict checking of property initialization in classes. */
        "noImplicitThis": true,
        /* Raise error on 'this' expressions with an implied 'any' type. */
        "alwaysStrict": true,
        /* Parse in strict mode and emit "use strict" for each source file. */

        /* Additional Checks */
        "noUnusedLocals": true,
        /* Report errors on unused locals. */
        // "noUnusedParameters": true,            /* Report errors on unused parameters. */
        // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
        // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

        /* Module Resolution Options */
        "moduleResolution": "node",
        /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
        // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
        // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
        // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
        // "typeRoots": [],                       /* List of folders to include type definitions from. */
        "types": ["jest", "node"],
        /* Type declaration files to be included in compilation. */
        "allowSyntheticDefaultImports": true,
        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
        "esModuleInterop": true,
        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
        // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
        // "allowUmdGlobalAccess": true,          /* Allow accessing UMD globals from modules. */

        /* Source Map Options */
        // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
        // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
        // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
        // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

        "resolveJsonModule": true,
        /* Experimental Options */
        "experimentalDecorators": true,
        /* Enables experimental support for ES7 decorators. */
        "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */
    },
    "include": [
        "./src/**/*"
    ],
    "exclude": ["node_modules", "jest.config.js"]
}
KurganskySergey commented 4 years ago

in dev dependencies "@babel/core": "7.8.4", "babel-loader": "8.0.6", "awesome-typescript-loader": "5.2.1", no .babelrc and clear package.json

pmmmwh commented 4 years ago

I'm more than happy to accept a PR to document this usage in the README.

pmmmwh commented 4 years ago

46 has been merged

Jack-Works commented 4 years ago

You don't have to use babel now! TypeScript-only solution is here #211

Jack-Works commented 3 years ago

Please checkout https://www.npmjs.com/package/react-refresh-typescript