2

以往都是用 ES5 语法写 react 组件并发布到 npm,最近,用 ES6 语法写了一个react拖曳组件,在本地调试完毕后,发布到 NPM 社区,出现了一系列问题,记录一下。
本文源码可参考这里

react 组件开发过程大致如下:在开发调试过程,将拖曳组件相关的代码放置在一个文件夹里,并通过

import DragMe from './libs/react-dragme/src/';

引用该react拖曳组件。

图片描述

本地开发调试完毕后,开始将此组件包装成一个符合NPM包规范的开源组件,并发布到NPM社区,再通过正式安装引用的方式使用该组件。过程如下:

1.初始化组件描述信息
cd /libs/react-dragme,初始化 package.json 文件

{
  "name": "react-dragme",
  "version": "1.0.11",
  "description": "a react component supporting elements' dragging",
  "main": "src/index.js",
  "repository": {
    "type": "git",
    "url": "https://github.com/hy20090501/react-dragMe.git"
  },
  "keywords": [
    "drag",
    "react"
  ],
  "author": "hy",
  "license": "ISC",
  "homepage": "https://github.com/hy20090501/react-dragMe/tree/master/libs/react-dragme"
}

2.开始发布
执行如下指令:

npm adduser
npm publish

发布完成

3.验证是否发布成功
安装npm社区上刚发布的react拖曳组件--react-dragme

npm install react-dragme --save

引用该组件:

//app.js
import React from 'react'
import ReactDOM from 'react-dom';
import { Layout, Menu } from 'antd';
//import DragMe from './libs/react-dragme/src/';
import DragMe from 'react-dragme';

用 webpack 构建编译整个应用,编译报错:

ERROR in ./~/_react-dragme@1.0.11@react-dragme/src/index.js                                                                                                                                             
Module parse failed: g:\gitspace\react-dragme\node_modules\_react-dragme@1.0.11@react-dragme\src\index.js Unexpected token (109:16)                                                                     
You may need an appropriate loader to handle this file type.                                                                                                                                            
SyntaxError: Unexpected token (109:16)                                                                                                                                                                  
    at Parser.pp$4.raise (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:2221:15)                                                                                               
    at Parser.pp.unexpected (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:603:10)                                                                                             
    at Parser.pp$3.parseExprAtom (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:1822:12)                                                                                       
    at Parser.pp$3.parseExprSubscripts (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:1715:21)                                                                                 
    at Parser.pp$3.parseMaybeUnary (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:1692:19)                                                                                     
    at Parser.pp$3.parseExprOps (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:1637:21)                                                                                        
    at Parser.pp$3.parseMaybeConditional (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:1620:21)                                                                               
    at Parser.pp$3.parseMaybeAssign (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:1597:21)                                                                                    
    at Parser.pp$3.parseParenAndDistinguishExpression (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:1861:32)                                                                  
    at Parser.pp$3.parseExprAtom (g:\gitspace\react-dragme\node_modules\_acorn@3.3.0@acorn\dist\acorn.js:1796:19)                                                                                       
 @ ./app.js 25:19-42                                                                                                                                                                                    
webpack: Failed to compile.  

为何在本地引入未出现打包报错,而发布后从 NPM 社区引入就出现这种错误?
估计是语法问题,排查了一段时间,原来问题来自 webpack 配置文件中加载器配置引起,webpack.config.js 当前配置如下:

// webpack.config.js

var path = require('path');

module.exports = {
    entry: path.resolve(__dirname, 'app.js'),
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.(png|jpg|gif)$/,
                loader: 'url-loader?limit=819200'
            },
            {
                test: /\.js$/,
                exclude: /node_modules|vue\/dist|vue-router\/|vue-loader\/|vue-hot-reload-api\//,
                loader: 'babel'
            },
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader?sourceMap'
            },
            {
                test: /\.(woff|svg|eot|ttf)\??.*$/,
                loader: 'url-loader?limit=50000&name=[path][name].[ext]'
            }
        ]
    }
};

原来,在webpack配置中,babel加载器中有个exclude配置属性设置成了node_modules,这将导致打包时默认对node_modules文件夹中的包不进行babel转码,而仅仅对app.js进行转码,这样就导致打包出现错误。

如何解决这个问题?
从打包效率上说,默认对node_modules文件夹中不进行babel转码,有助于提升打包效率。因此我选择将该组件先转化为ES5语法,然后发布到 NPM 社区,步骤如下:

进入libs/react-dragme文件夹,执行如下命令:

npm install --save-dev babel-cli babel-preset-es2015 babel-preset-react

修改 main 属性为 "main": "lib/index.js"
修改后完整的 package.json 文件:

{
  "name": "react-dragme",
  "version": "1.0.11",
  "description": "a react component supporting elements' dragging",
  "main": "lib/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "babel src -d lib",
    "prepublish": "npm run build"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/hy20090501/react-dragMe.git"
  },
  "keywords": [
    "drag",
    "react"
  ],
  "author": "hy",
  "license": "ISC",
  "homepage": "https://github.com/hy20090501/react-dragMe/tree/master/libs/react-dragme",
  "devDependencies": {
    "babel-cli": "^6.24.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1"
  },
  "_from": "react-dragme@1.0.11",
  "_resolved": "http://registry.npm.taobao.org/react-dragme/download/react-dragme-1.0.11.tgz"
}

执行 npm run build 首先将 ES6 语法转化为 ES5 语法,最后 npm publish 发布。

重复验证是否发布成功,打包正确。

总结:babel-loader 允许使用 ES6 语法进行开发,但目前 NPM 社区上的大部分开源包都是 ES5 语法定义的,
因此在发布自己的组件时要转换为ES5语法格式。


追寻
317 声望20 粉丝

混迹杭州 朝全栈的方向努力着...