node_modules中编译模块的Webpack配置

Webpack configuration for compiling module in node_modules

本文关键字:Webpack 配置 模块 编译 modules node      更新时间:2023-09-26

我的webpack/babel配置有问题。我已经将我的组件存储库(es6模块,内部没有webpack配置)安装为node_module。在这种情况下,它不起作用-我得到了"意外的令牌导入"错误(babel不传输es6代码)

但是,如果我将外部文件夹链接到node_modules(npm link./../component repository),则它工作正常,没有任何错误。我花了很多时间在上面,但仍然无法解决这个问题。

主要问题是如何在各个项目之间共享react组件。我的想法是将它们添加为依赖项。

edit:如何设置webpack&项目从node_modules文件夹编译ES6模块的babel?具有指向同级文件夹的npm链接的解决方案将不适用于生产。

edit2:我之所以在模块中保留es6代码,是因为在本地环境中,我想用组件npm链接同级文件夹(我可以编辑组件,然后将更改提交到它们的存储库)。我在3个项目之间共享组件。但在生产中,我想从git存储库自动安装它们作为依赖

本地env:上的结构

  • 组件(也是独立的git存储库)
  • 项目1
    • 节点模块
    • 组件(从../../components链接)
  • 项目2
    • 节点模块
    • 组件(从../../components链接)

生产结构:

  • 项目1
    • 节点模块
    • 组件(作为git存储库的依赖项)

发布较晚,但我今天遇到了这种情况。对我来说,问题是由babel require钩子引起的:

https://babeljs.io/docs/usage/require/

注意:默认情况下,对node_modules的所有要求都将被忽略。

基本上,babel没有用于任何指向node_modules的需求。这就是为什么代码适用于npm链接模块的原因,我猜babel跳过了忽略,因为路径不包含node_modules。

我能够通过更改requirehook中的忽略逻辑来解决这个问题,如下所示:

require('babel-register')({
  extensions: [".es6", ".es", ".jsx", ".js"],
  ignore: (absPath) => {
    if (absPath.lastIndexOf('node_modules') > absPath.indexOf('es6_module')) {
      return true;
    } else if (absPath.indexOf('es6_module') > -1) {
      return false;
    } else if (absPath.indexOf('node_modules') > -1) {
      return true;
    }
    return false;
  }
});

当然,请确保您的加载器具有相同的逻辑:

loaders: [
  {
    test: /'.jsx?$/,
    exclude: (absPath) => {
      if (absPath.lastIndexOf('node_modules') > absPath.indexOf('es6_module')) {
        return true;
      } else if (absPath.indexOf('es6_module') > -1) {
        return false;
      } else if (absPath.indexOf('node_modules') > -1) {
        return true;
      }
      return false;
    }
    loader: 'babel',
    query: {
            cacheDirectory: true,
            presets: ['es2015', 'react']
        }
  }

是否安装了es2015预设?

npm install babel-preset-es2015

第一个选项

那么loader可能是这样的:

loaders: [
  {
    test: /'.jsx?$/,
    exclude: /bower_components/,
    loader: 'babel',
    query: {
            cacheDirectory: true,
            presets: ['es2015', 'react']
        }
  }

这个加载程序现在应该遍历所有模块(但要注意:还要遍历所有node_module)并编译它们。预设的es2015正在管理您的ES6语法并将其转换为es5。

第二种选择

将您自己的节点模块安装到自己的目录

mkdir -p ./install/here/own_packages
npm install --prefix ./install/here <package>

因此,您可以在您的webpack.config 中执行此操作

loaders: [
  {
    test: /'.jsx?$/,
    exclude: /(node_modules|bower_components)/,
    loader: 'babel',
    query: {
            cacheDirectory: true,
            presets: ['es2015', 'react']
        }
  }

在那里,node_modules文件夹中的所有文件(以及bower_components)都将被忽略。您可以使用上面的命令行在src/js/components(或任何地方)中安装自己的npm模块。

许多用作依赖项的项目确保在发布npm之前编译到ES5

这之所以有用,有几个原因。

  1. 代码可以简单地添加到带有<script>的web浏览器中,它就会工作
  2. 它没有对消费应用程序将使用的捆绑工具做出任何假设

实现这一点的一种方法是在发布到npm之前通过babel传递库代码。

在建立时,我从React Bootstrap项目中获得了灵感。但这主要是因为我们想要构建可移植的、样式化的组件。然而,他们设置库以供使用的方式非常好

这样设置之后,消耗应用程序的配置非常简单,因为不需要进行babel编译。模块绑定器(类似于webpack)可以直接绑定模块(就像它对其他node_modules依赖项所做的那样)。