Webpack 无法识别节点模块中的 jsx 代码

vic*_*.ja 3 javascript reactjs webpack create-react-app webpack-4

我使用最新版本的create-react-app开始了一个新项目。我正在尝试使用私有 NPM 库。该库提供代码,应用程序负责导入包以从中转译组件。

\n\n

我将库的路径包含到babel-loader中,但 webpack 仍然没有将 babel 应用于它。

\n\n

这是我从导入到项目的唯一组件中收到的错误消息:

\n\n
./node_modules/PRIVATE-LIBRARY/Page404/index.js\nSyntaxError: /home/victor/app/node_modules/PRIVATE-LIBRARY/Page404/index.js: Unexpected token (12:2)\n\n  10 | \n  11 | const Page404 = () => (\n> 12 |   <div className="page404">\n     |   ^\n  13 |     <div className="page404__content">\n  14 |       <h2 className="page404__title">This is not the page<br/> you are looking for</h2>\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的webpack.config.dev.js文件

\n\n
\'use strict\';\n\nconst path = require(\'path\');\nconst webpack = require(\'webpack\');\nconst PnpWebpackPlugin = require(\'pnp-webpack-plugin\');\nconst HtmlWebpackPlugin = require(\'html-webpack-plugin\');\nconst CaseSensitivePathsPlugin = require(\'case-sensitive-paths-webpack-plugin\');\nconst InterpolateHtmlPlugin = require(\'react-dev-utils/InterpolateHtmlPlugin\');\nconst WatchMissingNodeModulesPlugin = require(\'react-dev-utils/WatchMissingNodeModulesPlugin\');\nconst ModuleScopePlugin = require(\'react-dev-utils/ModuleScopePlugin\');\nconst getCSSModuleLocalIdent = require(\'react-dev-utils/getCSSModuleLocalIdent\');\nconst getClientEnvironment = require(\'./env\');\nconst paths = require(\'./paths\');\nconst ManifestPlugin = require(\'webpack-manifest-plugin\');\nconst getCacheIdentifier = require(\'react-dev-utils/getCacheIdentifier\');\nconst ModuleNotFoundPlugin = require(\'react-dev-utils/ModuleNotFoundPlugin\');\n\n// Webpack uses `publicPath` to determine where the app is being served from.\n// In development, we always serve from the root. This makes config easier.\nconst publicPath = \'/\';\n// `publicUrl` is just like `publicPath`, but we will provide it to our app\n// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.\n// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.\nconst publicUrl = \'\';\n// Get environment variables to inject into our app.\nconst env = getClientEnvironment(publicUrl);\n\n// style files regexes\nconst cssRegex = /\\.css$/;\nconst cssModuleRegex = /\\.module\\.css$/;\nconst sassRegex = /\\.(scss|sass)$/;\nconst sassModuleRegex = /\\.module\\.(scss|sass)$/;\n\n// common function to get style loaders\nconst getStyleLoaders = (cssOptions, preProcessor) => {\n  const loaders = [\n    require.resolve(\'style-loader\'),\n    {\n      loader: require.resolve(\'css-loader\'),\n      options: cssOptions,\n    },\n    {\n      // Options for PostCSS as we reference these options twice\n      // Adds vendor prefixing based on your specified browser support in\n      // package.json\n      loader: require.resolve(\'postcss-loader\'),\n      options: {\n        // Necessary for external CSS imports to work\n        // https://github.com/facebook/create-react-app/issues/2677\n        ident: \'postcss\',\n        plugins: () => [\n          require(\'postcss-flexbugs-fixes\'),\n          require(\'postcss-preset-env\')({\n            autoprefixer: {\n              flexbox: \'no-2009\',\n            },\n            stage: 3,\n          }),\n        ],\n      },\n    },\n  ];\n  if (preProcessor) {\n    loaders.push(require.resolve(preProcessor));\n  }\n  return loaders;\n};\n\n// This is the development configuration.\n// It is focused on developer experience and fast rebuilds.\n// The production configuration is different and lives in a separate file.\nmodule.exports = {\n  mode: \'development\',\n  // You may want \'eval\' instead if you prefer to see the compiled output in DevTools.\n  // See the discussion in https://github.com/facebook/create-react-app/issues/343\n  devtool: \'cheap-module-source-map\',\n  // These are the "entry points" to our application.\n  // This means they will be the "root" imports that are included in JS bundle.\n  entry: [\n    // Include an alternative client for WebpackDevServer. A client\'s job is to\n    // connect to WebpackDevServer by a socket and get notified about changes.\n    // When you save a file, the client will either apply hot updates (in case\n    // of CSS changes), or refresh the page (in case of JS changes). When you\n    // make a syntax error, this client will display a syntax error overlay.\n    // Note: instead of the default WebpackDevServer client, we use a custom one\n    // to bring better experience for Create React App users. You can replace\n    // the line below with these two lines if you prefer the stock client:\n    // require.resolve(\'webpack-dev-server/client\') + \'?/\',\n    // require.resolve(\'webpack/hot/dev-server\'),\n    require.resolve(\'react-dev-utils/webpackHotDevClient\'),\n    // Finally, this is your app\'s code:\n    paths.appIndexJs,\n    // We include the app code last so that if there is a runtime error during\n    // initialization, it doesn\'t blow up the WebpackDevServer client, and\n    // changing JS code would still trigger a refresh.\n  ],\n  output: {\n    // Add /* filename */ comments to generated require()s in the output.\n    pathinfo: true,\n    // This does not produce a real file. It\'s just the virtual path that is\n    // served by WebpackDevServer in development. This is the JS bundle\n    // containing code from all our entry points, and the Webpack runtime.\n    filename: \'static/js/bundle.js\',\n    // There are also additional JS chunk files if you use code splitting.\n    chunkFilename: \'static/js/[name].chunk.js\',\n    // This is the URL that app is served from. We use "/" in development.\n    publicPath: publicPath,\n    // Point sourcemap entries to original disk location (format as URL on Windows)\n    devtoolModuleFilenameTemplate: info =>\n      path.resolve(info.absoluteResourcePath).replace(/\\\\/g, \'/\'),\n  },\n  optimization: {\n    // Automatically split vendor and commons\n    // https://twitter.com/wSokra/status/969633336732905474\n    // https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366\n    splitChunks: {\n      chunks: \'all\',\n      name: false,\n    },\n    // Keep the runtime chunk seperated to enable long term caching\n    // https://twitter.com/wSokra/status/969679223278505985\n    runtimeChunk: true,\n  },\n  resolve: {\n    // This allows you to set a fallback for where Webpack should look for modules.\n    // We placed these paths second because we want `node_modules` to "win"\n    // if there are any conflicts. This matches Node resolution mechanism.\n    // https://github.com/facebook/create-react-app/issues/253\n    modules: [\'node_modules\'].concat(\n      // It is guaranteed to exist because we tweak it in `env.js`\n      process.env.NODE_PATH.split(path.delimiter).filter(Boolean)\n    ),\n    // These are the reasonable defaults supported by the Node ecosystem.\n    // We also include JSX as a common component filename extension to support\n    // some tools, although we do not recommend using it, see:\n    // https://github.com/facebook/create-react-app/issues/290\n    // `web` extension prefixes have been added for better support\n    // for React Native Web.\n    extensions: [\'.mjs\', \'.web.js\', \'.js\', \'.json\', \'.web.jsx\', \'.jsx\'],\n    alias: {\n      // Support React Native Web\n      // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/\n      \'react-native\': \'react-native-web\',\n      components: path.resolve(paths.appSrc, \'components\'),\n      assets: path.resolve(paths.appSrc, \'assets\'),\n      utils: path.resolve(paths.appSrc, \'utils\'),\n    },\n    plugins: [\n      // Adds support for installing with Plug\'n\'Play, leading to faster installs and adding\n      // guards against forgotten dependencies and such.\n      PnpWebpackPlugin,\n      // Prevents users from importing files from outside of src/ (or node_modules/).\n      // This often causes confusion because we only process files within src/ with babel.\n      // To fix this, we prevent you from importing files out of src/ -- if you\'d like to,\n      // please link the files into your node_modules/ and let module-resolution kick in.\n      // Make sure your source files are compiled, as they will not be processed in any way.\n      new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),\n    ],\n  },\n  resolveLoader: {\n    plugins: [\n      // Also related to Plug\'n\'Play, but this time it tells Webpack to load its loaders\n      // from the current package.\n      PnpWebpackPlugin.moduleLoader(module),\n    ],\n  },\n  module: {\n    strictExportPresence: true,\n    rules: [\n      // Disable require.ensure as it\'s not a standard language feature.\n      { parser: { requireEnsure: false } },\n\n      // First, run the linter.\n      // It\'s important to do this before Babel processes the JS.\n      {\n        test: /\\.(js|mjs|jsx)$/,\n        enforce: \'pre\',\n        use: [\n          {\n            options: {\n              formatter: require.resolve(\'react-dev-utils/eslintFormatter\'),\n              eslintPath: require.resolve(\'eslint\'),\n\n            },\n            loader: require.resolve(\'eslint-loader\'),\n          },\n        ],\n        include: paths.appSrc,\n      },\n      {\n        // "oneOf" will traverse all following loaders until one will\n        // match the requirements. When no loader matches it will fall\n        // back to the "file" loader at the end of the loader list.\n        oneOf: [\n          // "url" loader works like "file" loader except that it embeds assets\n          // smaller than specified limit in bytes as data URLs to avoid requests.\n          // A missing `test` is equivalent to a match.\n          {\n            test: [/\\.bmp$/, /\\.gif$/, /\\.jpe?g$/, /\\.png$/],\n            loader: require.resolve(\'url-loader\'),\n            options: {\n              limit: 10000,\n              name: \'static/media/[name].[hash:8].[ext]\',\n            },\n          },\n          // Process application JS with Babel.\n          // The preset includes JSX, Flow, and some ESnext features.\n          {\n            test: /\\.(js|mjs|jsx)$/,\n            include: [\n              paths.appSrc,\n              paths.privateLib,\n            ],\n            loader: require.resolve(\'babel-loader\'),\n            options: {\n              customize: require.resolve(\n                \'babel-preset-react-app/webpack-overrides\'\n              ),\n\n              plugins: [\n                [\n                  require.resolve(\'babel-plugin-named-asset-import\'),\n                  {\n                    loaderMap: {\n                      svg: {\n                        ReactComponent: \'@svgr/webpack?-prettier,-svgo![path]\',\n                      },\n                    },\n                  },\n                ],\n              ],\n              // This is a feature of `babel-loader` for webpack (not Babel itself).\n              // It enables caching results in ./node_modules/.cache/babel-loader/\n              // directory for faster rebuilds.\n              cacheDirectory: true,\n              // Don\'t waste time on Gzipping the cache\n              cacheCompression: false,\n            },\n          },\n          // Process any JS outside of the app with Babel.\n          // Unlike the application JS, we only compile the standard ES features.\n          {\n            test: /\\.(js|mjs)$/,\n            exclude: /@babel(?:\\/|\\\\{1,2})runtime/,\n            loader: require.resolve(\'babel-loader\'),\n            options: {\n              babelrc: false,\n              configFile: false,\n              compact: false,\n              presets: [\n                [\n                  require.resolve(\'babel-preset-react-app/dependencies\'),\n                  { helpers: true },\n                ],\n              ],\n              cacheDirectory: true,\n              // Don\'t waste time on Gzipping the cache\n              cacheCompression: false,\n\n              // If an error happens in a package, it\'s possible to be\n              // because it was compiled. Thus, we don\'t want the browser\n              // debugger to show the original code. Instead, the code\n              // being evaluated would be much more helpful.\n              sourceMaps: false,\n            },\n          },\n          // "postcss" loader applies autoprefixer to our CSS.\n          // "css" loader resolves paths in CSS and adds assets as dependencies.\n          // "style" loader turns CSS into JS modules that inject <style> tags.\n          // In production, we use a plugin to extract that CSS to a file, but\n          // in development "style" loader enables hot editing of CSS.\n          // By default we support CSS Modules with the extension .module.css\n          {\n            test: cssRegex,\n            exclude: cssModuleRegex,\n            use: getStyleLoaders({\n              importLoaders: 1,\n            }),\n          },\n          // Adds support for CSS Modules (https://github.com/css-modules/css-modules)\n          // using the extension .module.css\n          {\n            test: cssModuleRegex,\n            use: getStyleLoaders({\n              importLoaders: 1,\n              modules: true,\n              getLocalIdent: getCSSModuleLocalIdent,\n            }),\n          },\n          // Opt-in support for SASS (using .scss or .sass extensions).\n          // Chains the sass-loader with the css-loader and the style-loader\n          // to immediately apply all styles to the DOM.\n          // By default we support SASS Modules with the\n          // extensions .module.scss or .module.sass\n          {\n            test: sassRegex,\n            exclude: sassModuleRegex,\n            use: getStyleLoaders({ importLoaders: 2 }, \'sass-loader\'),\n          },\n          // Adds support for CSS Modules, but using SASS\n          // using the extension .module.scss or .module.sass\n          {\n            test: sassModuleRegex,\n            use: getStyleLoaders(\n              {\n                importLoaders: 2,\n                modules: true,\n                getLocalIdent: getCSSModuleLocalIdent,\n              },\n              \'sass-loader\'\n            ),\n          },\n          // "file" loader makes sure those assets get served by WebpackDevServer.\n          // When you `import` an asset, you get its (virtual) filename.\n          // In production, they would get copied to the `build` folder.\n          // This loader doesn\'t use a "test" so it will catch all modules\n          // that fall through the other loaders.\n          {\n            // Exclude `js` files to keep "css" loader working as it injects\n            // its runtime that would otherwise be processed through "file" loader.\n            // Also exclude `html` and `json` extensions so they get processed\n            // by webpacks internal loaders.\n            exclude: [/\\.(js|mjs|jsx)$/, /\\.html$/, /\\.json$/],\n            loader: require.resolve(\'file-loader\'),\n            options: {\n              name: \'static/media/[name].[hash:8].[ext]\',\n            },\n          },\n        ],\n      },\n      // ** STOP ** Are you adding a new loader?\n      // Make sure to add the new loader(s) before the "file" loader.\n    ],\n  },\n  plugins: [\n    // Generates an `index.html` file with the <script> injected.\n    new HtmlWebpackPlugin({\n      inject: true,\n      template: paths.appHtml,\n    }),\n    // Makes some environment variables available in index.html.\n    // The public URL is available as %PUBLIC_URL% in index.html, e.g.:\n    // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">\n    // In development, this will be an empty string.\n    new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),\n    // This gives some necessary context to module not found errors, such as\n    // the requesting resource.\n    new ModuleNotFoundPlugin(paths.appPath),\n    // Makes some environment variables available to the JS code, for example:\n    // if (process.env.NODE_ENV === \'development\') { ... }. See `./env.js`.\n    new webpack.DefinePlugin(env.stringified),\n    // This is necessary to emit hot updates (currently CSS only):\n    new webpack.HotModuleReplacementPlugin(),\n    // Watcher doesn\'t work well if you mistype casing in a path so we use\n    // a plugin that prints an error when you attempt to do this.\n    // See https://github.com/facebook/create-react-app/issues/240\n    new CaseSensitivePathsPlugin(),\n    // If you require a missing module and then `npm install` it, you still have\n    // to restart the development server for Webpack to discover it. This plugin\n    // makes the discovery automatic so you don\'t have to restart.\n    // See https://github.com/facebook/create-react-app/issues/186\n    new WatchMissingNodeModulesPlugin(paths.appNodeModules),\n    // Moment.js is an extremely popular library that bundles large locale files\n    // by default due to how Webpack interprets its code. This is a practical\n    // solution that requires the user to opt into importing specific locales.\n    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack\n    // You can remove this if you don\'t use Moment.js:\n    new webpack.IgnorePlugin(/^\\.\\/locale$/, /moment$/),\n    // Generate a manifest file which contains a mapping of all asset filenames\n    // to their corresponding output file so that tools can pick it up without\n    // having to parse `index.html`.\n    new ManifestPlugin({\n      fileName: \'asset-manifest.json\',\n      publicPath: publicPath,\n    }),\n  ],\n\n  // Some libraries import Node modules but don\'t use them in the browser.\n  // Tell Webpack to provide empty mocks for them so importing them works.\n  node: {\n    dgram: \'empty\',\n    fs: \'empty\',\n    net: \'empty\',\n    tls: \'empty\',\n    child_process: \'empty\',\n  },\n  // Turn off performance processing because we utilize\n  // our own hints via the FileSizeReporter\n  performance: false,\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中paths.privateLib包含 privateLib: resolveApp(\'node_modules/PRIVATE-LIBRARY\'),

\n\n

我\xe2\x80\x99m 在其他三个带有 webpack 3 的应用程序中使用这个库没有问题

\n

vic*_*.ja 5

问题在于.babelrc"babel"at的默认行为package.json发生了变化。

对于babel之前的版本v 7,默认行为是babel-loader还包含node-modules文件。这种情况发生了变化,因为这种行为导致了一些难以跟踪的错误。

现在,如果您希望配置也影响您的node_modules,您应该定义一个babel.config.js文件而不是configs.babelrc"babel"at package.jsonconfigs。

默认情况下,babel.config.js会影响. 它应该放置在您的文件的同一级别node_modules package.json

这是我的配置示例:

module.exports = function (api) {
  const presets = ['react-app'];
  api.cache.never();

  return { presets };
};
Run Code Online (Sandbox Code Playgroud)

Babel 文档以获取有关 babel.config.js 的更多信息