NEJ代码中如何渐进地引入React

阿凡达2018-07-04 10:52

React实在太火了,比如Twitter最近放出了基于React的新版手机版,比如阿里也积累了基于React的组件库。

上面只是表象,所以为什么要引入React呢
  • React是需要transpile的,顺带着可以使用ES2105,享受最新的语言进步的果实
  • 先写一段代码去呈现,再写另外一段代码去更新界面的方式已经落后了,样式、模版和脚本应该更紧密一点,更内聚一点
  • 虚拟DOM Diff提升性能
现有代码是基于NEJ的,而React是需要 transpile的,和自己的老搭档webpack关系也很亲密,而NEJ也有自己的打包工具toolkit2,所以如何渐进地引入React呢。

babel

NEJ的模块系统跟AMD很类似,而AMD有现成的babel插件可以转,对该插件稍微改造下,是能够为NEJ服务的。
但前端不只有JS,还有CSS和图片等其他资源,特别是CSS,如果使用webpack,可以启用css-loader的CSS Module,放弃了真是可惜,所以webpack还是不可少的。

组件

webpack不只可以打包应用代码,还可以打包库代码,可以配置webpack打包React组件以成NEJ组件。
这个有几个注意的地方
  • output.libraryTarget设成amd
  • 外部依赖使必须在externals里注明
  • webpack runtime和一些公用的代码比如css-loader使用CommonsChunkPlugin插件抽离出来
以下以webpack 2的配置为例
var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: {
        toast: './react_components/toast/src/toast.js',
        tooltip: './react_components/tooltip/src/tooltip.js'
    },

    output: {
        path: path.resolve(__dirname, '../js/components'),
        filename: '[name].js',
        libraryTarget: 'amd'
    },
    resolve: {
        extensions: [".js", ".json", ".css", ".jsx"]
    },
    externals: {
        "react": {
            amd: "pro/lib/adapter/react"
        },
        "toast": {
            amd: "pro/components/toast"
        }
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
          names: "webpack-common"
        })
    ],
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                use: 'babel-loader'
            },

            {
                test: /\.css$/,
                use: [
                    {
                        loader: "style-loader"
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 1,
                            modules: 1
                        }
                    },
                    {
                        loader: 'postcss-loader'
                    }
                ]

            }
        ]
    }
};
// js/lib/adapter/react.js
NEJ.define([], function() {
    return window.React;
});

本文来自网易实践者社区,经作者江云唬授权发布。