pmmmwh / react-refresh-webpack-plugin

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

You may need an additional loader to handle the result of these loaders #540

Closed QingLianDuo closed 2 years ago

QingLianDuo commented 2 years ago

Failed to compile.

../text.ts 10:28 Module parse failed: Unexpected token (10:28) File was processed with these loaders:

jetonk commented 2 years ago

I get the same error by using CRA React with TypeScript and Craco when trying to access files outside of /src Screenshot 2021-12-07 at 19 06 31

pmmmwh commented 2 years ago

I get the same error by using CRA React with TypeScript and Craco when trying to access files outside of /src Screenshot 2021-12-07 at 19 06 31

This is expected behaviour with CRA - it doesn't support transpiling source code outside of src with the full Babel setup. You probably need more transforms to handle the TS code you're loading outside of src.

pmmmwh commented 2 years ago

Failed to compile.

../text.ts 10:28 Module parse failed: Unexpected token (10:28) File was processed with these loaders:

* ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
  You may need an additional loader to handle the result of these loaders.
  |
  | // getWords: Get the word array from text. A single Chinese character is a word.

export function getWords(txt: string) { | const words = []; | let word = '';

Seemingly your TS files are not transpiled properly, it should be something to do with your TS setup?

christopherGdynia commented 2 years ago

I have got the same issue. It only appears in local packages in my turborepos, which uses yarn workspaces.

In Reactcomponents I could resolve it, with exporting the type of my props

tscsonfig base config ```json { "$schema": "https://json.schemastore.org/tsconfig", "display": "Default", "compilerOptions": { "allowJs": true, "composite": false, "declaration": true, "declarationMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "incremental": true, "inlineSources": false, "isolatedModules": true, "lib": ["ES2021", "DOM", "DOM.Iterable"], "module": "esnext", "moduleResolution": "node", "noUnusedLocals": false, "noUnusedParameters": false, "preserveWatchOutput": true, "resolveJsonModule": true, "skipLibCheck": true, "strict": true, "typeRoots": ["../../node_modules/@types"] } } ``` the config ```json { "$schema": "https://json.schemastore.org/tsconfig", "display": "React Library", "extends": "./base.json", "compilerOptions": { "jsx": "react-jsx", "noEmit": false, "target": "ES5" } } ```
Module parse failed: Unexpected token (11:54) File was processed with these loaders: * ../../node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js * You may need an additional loader to handle the result of these loaders. ```ts import { parseISO } from "date-fns"; import { isIsoDateString } from "./dateFormatHandler"; export * from "./constants"; export * from "./dateFormatHandler"; export * from "./searchParamBuilder"; export * from "./validation/errorMessages"; export const API_BASE_URL = process.env.API_BASE_URL ?? "https://localhost:44371/api/"; export const AUTH_BASE_URL = process.env.AUTH_BASE_URL ?? "https://localhost:7126/"; export const JWT_TIME = +(process.env.JWT_TIME ?? 18); //20 export const REFRESH_TIME = +(process.env.REFRESH_TIME ?? 20); //20 ```

I appreciate every help

EDIT: my folder structure:

the error happened in utils, but I am only using it with one app yet and the doesn't use everything from the packages

pmmmwh commented 2 years ago

I have got the same issue. It only appears in local packages in my turborepos, which uses yarn workspaces.

This seems like you have un-transpiled TS code that was included by this loader, you probably need to add TS transpile to those files?

designbyadrian commented 2 years ago

I get this issue when trying to use optional chaining, i.e const myVar = myObject?.theProperty

Inside a CRA app running react-scripts 4.0.3 with default options. Do I need to add a .babelrc as well?

christopherGdynia commented 2 years ago

I have got the same issue. It only appears in local packages in my turborepos, which uses yarn workspaces.

This seems like you have un-transpiled TS code that was included by this loader, you probably need to add TS transpile to those files?

Ok, how do I implement a loader in cra with typescript? This might be a nooby question, but I don't have any ideas

pmmmwh commented 2 years ago

I have got the same issue. It only appears in local packages in my turborepos, which uses yarn workspaces.

This seems like you have un-transpiled TS code that was included by this loader, you probably need to add TS transpile to those files?

Ok, how do I implement a loader in cra with typescript? This might be a nooby question, but I don't have any ideas

The problem with CRA is that it does not support transpiling code outside of the project's src directory - so what you would need to do is to have the code transpiled somehow before feeding it into the CRA project, or use something like react-app-rewired or craco to inject another Babel loader rule so that the code imported from your other workspaces would be transpiled.

pmmmwh commented 2 years ago

I get this issue when trying to use optional chaining, i.e const myVar = myObject?.theProperty

Inside a CRA app running react-scripts 4.0.3 with default options. Do I need to add a .babelrc as well?

I'm not sure about syntax support in CRA versions, maybe you should ask there? Adding a .babelrc would definitely help.

dsuresh-ap commented 2 years ago

So we have this same issue with no real solution just a workaround. The issue for us is that we have a npm workspace setup

The common folder is symlinked in node_modules. This means the dist/ folder as well as source code is symlinked. On first run of CRA webpack is fine but when the common folder gets rebuilt, fast refresh kicks in and tries to transpile the .ts code outside common/dist. Is there a proper way to disable that?

image

The workaround we have is using react-rewired with CRA. Then I created a dummy loader that basically ingests the .ts files and does nothing.

Example:

//ignore-loader.js
/**
 * A webpack loader that does nothing. Used as a workaround for an issue
 * with react refresh and common.
 * @see config-overrides.js
 */
module.exports = function loader(source) {
  return "";
};
// config-overrides.js which is part of react-rewired
const webpack = require("webpack");
const path = require("path");
module.exports = function override(config, env) {
  // This loader ignores .ts files in common as a workaround.
  // For some reason when common is rebuilt, react refresh
  // tries to compile .ts sources from common
  const rulesOneOf = config.module.rules[1].oneOf;
  rulesOneOf.splice(rulesOneOf.length - 1, 0, {
    test: /\.ts$/,
    include: path.join(__dirname, "..", "common"),
    use: {
      loader: path.resolve(__dirname, "ignore-loader.js")
    }
  });

  return config;
};

Anyone have any solutions?? Basically we DON'T want the .ts code in the symbolic linked node_modules to be transpiled.

christopherGdynia commented 2 years ago

I have switched from CRA to NextJS, this works, in the turborepo example is a working solution.

pmmmwh commented 2 years ago

Closing as this is expected behaviour - CRA does not transpile outside of src, and it is the responsibility of the user to handle that.

robertcoopercode commented 2 years ago

For those wondering how to do this with craco, here is some code that I used to get things working:

const fs = require('fs');
const path = require('path');

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath);

module.exports = {
    plugins: [
        {
            plugin: require('craco-babel-loader'),
            options: {
                includes: [resolveApp('../shared')],
            },
        },
    ],
};

shared is the name of a directory of shared code used in a monorepo. Here is my repo structure:

node_modules/
package.json
packages/
    client/
        node_modules/
        package.json
        craco.config.json
    server/
        node_modules/
        package.json
    shared/
        node_modules/
        package.json
yatessss commented 2 years ago

this my way can be resolve in craco.config.js

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);

....

configure: (webpackConfig, {env, paths}) => {
     ...
      // 为了可以解析src目录外的文件 添加一个loader
      const {matches} = getLoaders(webpackConfig, loaderByName('babel-loader'));
      addBeforeLoader(webpackConfig, loaderByName('babel-loader'), {
        ...matches[0].loader,
        include: [resolveApp('../shared')],
      });
     ...
      return webpackConfig;
    },
JohnXG commented 2 years ago

following @robertcoopercode's suggestion, I found a bit more info re CRA vs craco on youtube https://youtu.be/zQUpNa1hZIA?t=595

and here is the code from the video, and don't forget to change package.json start script to use craco start.

const path = require("path");
const { getLoader, loaderByName } = require("@craco/craco");

const packages = [];
console.log(__dirname);
packages.push(path.join(__dirname, "./path-to-the-shared-package"));
packages.push(path.join(__dirname, "./path-to-another-shared-package"));  //you can add as many as you need, but this gets slightly annoying

module.exports = {
  webpack: {
    configure: (webpackConfig, arg) => {
      const { isFound, match } = getLoader(
        webpackConfig,
        loaderByName("babel-loader")
      );
      if (isFound) {
        const include = Array.isArray(match.loader.include)
          ? match.loader.include
          : [match.loader.include];

        match.loader.include = include.concat(packages);
      }
      return webpackConfig;
    },
  },
};
ViieeS commented 1 year ago

In my case I have a published package with transpiled code, so dist contains .js along with d.ts. However, this loader trying to import .d.ts from .js file and return this error. $ tsc returns no errors.

package.json

"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
   "build": "tsc --outDir dist/",
   "prepare": "npm run build"
},

tsconfig.json

{
  "compilerOptions": {
    "declaration": true,
    "target": "es6",
    "module": "esnext",
    "moduleResolution": "node",
    "lib": [
      "es6",
      "dom"
    ],
    "noImplicitAny": true,
    "outDir": "dist",
    "rootDir": ".",
    "typeRoots": [
      "node_modules/@types"
    ]
  },
  "exclude": [
    "dist",
    "node_modules"
  ]
}
Makinde1034 commented 7 months ago

"types": "./dist/index.d.ts", "scripts": { "build": "tsc --outDir dist/", "prepare": "npm run build" },

Were you able to resolve this issue?