React webpack / browserify "unexpected token"

3
我有一个自己创建的npm模块color-picker-react,但每次尝试引入它来测试时都会出现以下错误:
Unexpected token <
You may need an appropriate loader to handle this file type.

我使用了react-starterkit,并像这样将其包含在main.js文件中:

var ReactDOM = require('react-dom');
var ColorPicker = require('color-picker-react');
ReactDOM.render(<ColorPicker />, document.getElementById('app'));

然后当我运行 gulp 命令时,它会去运行 webpack ,但是出现了错误。这是 webpack.config.js 的配置文件:

module.exports.getConfig = function(type) {

  var isDev = type === 'development';

  var config = {
    entry: './app/scripts/main.js',
    output: {
      path: __dirname,
      filename: 'main.js'
    },
    debug : isDev,
    module: {
      loaders: [{
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: ['react', 'es2015']
        }
      }]
    }
  };

  if(isDev){
    config.devtool = 'eval';
  }

  return config;
}

我已经尝试了我能想到的所有方法,但还是无法使它正常工作。我没有在任何地方使用ES6,并且我尝试过许多不同的React入门套件,但我就是无法使它工作。请帮忙!!!

顺便说一句,当我将其克隆到本地并使用browserify构建app.js时,我可以使该项目运行,步骤如下:browserify -t [ babelify --presets [ react ] ] app.js -o bundle.js


你的文件扩展名是jsx吗? - elclanrs
不是原来的问题,但如果我将它们重命名为.jsx仍然无法工作。 - cocoa
1个回答

3
为解决问题,如果您不是npm模块的作者(但您应该选择另一个模块),则需删除exclude: /node_modules/
组件color-picker-react似乎没有发布版本或编译jsx的脚本。因此,您需要自己编译jsx文件并使用webpack实时编译。
除了仅删除exclude: /node_modules/,您还可以使用正则表达式模式来排除所有/node_modules/,但保留/node_modules/color-picker-react文件夹。
//will exclude all modules except `color-picker-react`
exclude: /node_modules\/(?!color-picker-react).*\//,

创建npm模块的基础知识:

正确的npm模块设置是添加一个prepublish脚本,以确保在上传到NPM之前自动进行编译

因此,当您将模块推送到npm时,用户无需编译模块,只需require它即可。

以node_module为例:https://github.com/securingsincity/react-ace/blob/master/package.json

package.json文件指定了在需要该模块时入口点是哪个文件

 "main": "lib/ace.js",

您可以在Github代码库中看到,lib文件夹并不存在,因为已添加至.gitignore。但是下面这行代码:
  "prepublish": "npm run clean && npm run build"

在上传到NPM之前,会先运行一些操作,因此在npm仓库中,lib/文件夹已经存在,并且当您执行npm install --save react-ace时,可以在node_modules/react-ace/文件夹中看到它。

这是一个很好的链接,解释了如何使用es6构建npm模块,例如http://javascriptplayground.com/blog/2015/10/authoring-modules-in-es6/

编辑说明react-color-picker模块需要做什么:

抱歉我没有看到您是该模块的作者,因此您应该采用以下解决方案

例如,react-color-picker没有预发布脚本,主文件是index.js

var ColorPicker = require('./colorpicker.js'); // require a file with jsx will throw an error if not precompiled 

module.exports = ColorPicker;

因此会抛出语法错误。

要在其他应用程序中使用npm模块:

  1. 为npm模块创建webpack配置,以处理使用jsx编写的react组件的转换(您可以采用此模块的某些webpack配置https://github.com/securingsincity/react-ace 设置libraryTarget: 'umd',这样您的模块将更易于从各种模块系统(全局、AMD、CommonJS)中使用)。
  2. 添加一个prepublish脚本,输出颜色选择器的预编译版本(lib/pickedprecompiled.js)。
  3. 更改main"main": "lib/pickedprecompiled.js",

如果我替换 exclude: /node_modules/ 并执行 include: /node_modules/color-picker-react,那么我仍然会收到错误。我应该如何进行发布构建或脚本?这样能解决问题吗? - cocoa
你应该移除排除的那行代码,或者找到一个正则表达式来排除所有node_modules,除了color-picker-react。我修改了我的答案以提高清晰度,简单的解决方法是删除 exclude: /node_modules/ 这一行代码。 - Aaleks
1
排除可能有效,但许多其他webpack项目也可能在其配置中排除了所有node_modules,因此使用此npm模块的任何人都可能遇到问题。其他npm模块如何处理这个问题 - 他们是否预编译他们的JS? - Kevin Qi
是的,他们通过添加一个 prepublish 脚本来预编译他们的 JS,以确保在上传到 NPM 之前自动进行编译,我编辑了我的答案以提供更多关于这方面的信息。所以 color-picker-react 的设计不太好。例如,没有 prepublish 脚本来处理 jsx 转换。 - Aaleks
@cocoa 我修改了我的答案,说明如何创建和重构模块。很抱歉我错过了你是该模块的作者这一点,所以你应该直接更改你的 color-picker-react 模块。 - Aaleks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接