ElemeFE / element-react

Element UI
https://elemefe.github.io/element-react/index
MIT License
2.84k stars 443 forks source link

关于按需加载的问题 #533

Open chenyihao2621023 opened 7 years ago

chenyihao2621023 commented 7 years ago

看了几个有关issue ,如babel-plugin-component失效 , 但是我按照您说的 tree-shaking 却还是未能减少js的体积,可能是webpack未配置好,可以参考下您项目的webpack配置么?或者,近期有发布新的babel-plugin的打算么,因为公司最近在选 react的ui框架,按需加载这个需求真的很重要。感谢!

e1emeb0t commented 7 years ago

参考 https://github.com/eleme/element-react/issues/490, babel-plugin-component是为了按需编译css的, webpack可以参考如下配置:

resolve: {
    mainFields: ['jsnext:main', 'main'] // <--- Add this line
}
chenyihao2621023 commented 7 years ago

感谢您的及时回复! 下面是我的webpack.base.conf.js

resolve: { extensions: ['.js', '.jsx', '.json'], mainFields: ['jsnext:main', 'main'], alias: { '@': resolve('src'), }

// 下面是 Hello.jsx 组件 import { Button } from 'element-react/next';

然后的是这个错 Cannot assign to read only property 'exports' of object '#' 是我配置的有问题么 麻烦您了

matth3wga0 commented 7 years ago

正常引用组件, 替换element-react/nextelement-react:

import { Button } from 'element-react';
chenyihao2621023 commented 7 years ago

已试 确实减少了一定体积 可是幅度不大。同样是引入一个button element-react引入的体积比ant-design的体积 打包后 要多 300k(vendor.js) , 所以还是想请教贵团队 有优化的方法吗 谢谢!

e1emeb0t commented 7 years ago

element-theme-default的CSS样式你抽离出来了么? 能贴一下你的loaders和plugins的配置么?

chenyihao2621023 commented 7 years ago

感谢您的及时回复!

// babel-lodaer
rules: [
            {
                test: /\.jsx?$/,
                loader: 'babel-loader',
                include: [resolve('src')],
                exclude: /node_modules/
            }
        ],
  // css loader
function generateLoaders(loader, loaderOptions) {
        const loaders = [cssLoader];
        if (loader) {
            loaders.push({
                loader: `${loader}-loader`,
                options: Object.assign({}, loaderOptions, {
                    sourceMap: options.sourceMap,
                }),
            });
        }

        if (options.extract) {
            return ExtractTextPlugin.extract({
                use: loaders,
                fallback: '',
            });
        }
        return ['style-loader'].concat(loaders);
    }

    return {
        css: generateLoaders(),
        postcss: generateLoaders(),
        less: generateLoaders('less'),
        sass: generateLoaders('sass', { indentedSyntax: true }),
        scss: generateLoaders('sass'),
        stylus: generateLoaders('stylus'),
        styl: generateLoaders('stylus'),
    };

这个脚手架 是我改装vue的 element-theme-default 的样式没有抽出来, 应该怎么配置呢,望不吝赐教,谢谢!

e1emeb0t commented 7 years ago

你需要用到extract-text-webpack-plugin, 比如:

const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("styles.css"),
  ]
}

看到你用了extract-text-webpack-plugin, 但是options.extract貌似都是undefined, 抽离的逻辑跳过了.

chenyihao2621023 commented 7 years ago

这个插件已配置好,可能是我没有描述清楚 , 我用ant-design举下例子

import { Button as AntButton } from 'antd'; // 100k

import { Button as AntButton, Input as AntInput } from 'antd'; // 200k

就是说 js 是随着我引入组件的多少, 而逐级增加 而

import { Button } from 'element-react/next';  //500k

import { Button, Input } from 'element-react/next';  //500k

总是一个固定的大小,不会随我引入组件的多少 而变化

e1emeb0t commented 7 years ago

按道理说这应该是编译器比如webpack来做的, 只要用了es6的import/export, webpack只会打包import的模块, 我抽空看下antd的项目结构.

chenyihao2621023 commented 7 years ago

好的 感谢您!

e1emeb0t commented 7 years ago

我清楚这500k是什么了, 因为element-theme-default引入了所有组件的样式, 虽然按需加载了组件的js, 但是css还是加载的所有组件的, 导致编译后的bundle很大, 所以还是回到了最初的问题上: babel-plugin-component, 等待issue https://github.com/eleme/element-react/issues/305 解决吧.

chenyihao2621023 commented 7 years ago
import { Button } from 'element-react/next';  //500k

import { Button, Input } from 'element-react/next';  //500k

但是 这种写法 为什么打包出来的js 大小相同呢 不是应该多出来 Input 的js部分吗

e1emeb0t commented 7 years ago

Input组件本身就很小, 编译后看不出差别, 你可以试一下比较大的组件, 比如Select, Table, DatePicker.

chenyihao2621023 commented 7 years ago
import { Button, DatePicker, Table } from 'element-react/next'

依旧大小不变

e1emeb0t commented 7 years ago

看了下node_modules/antd/es/index.js:

// this file is not used if use https://github.com/ant-design/babel-plugin-import
var ENV = process.env.NODE_ENV;
if (ENV !== 'production' && ENV !== 'test' && typeof console !== 'undefined' && console.warn && typeof window !== 'undefined') {
    console.warn('You are using a whole package of antd, ' + 'please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.');
}

babel-plugin-import这个插件起了至关重要的作用:

import { Button } from 'antd';

ReactDOM.render(<div>
  <Button>xxxx</Button>
</div>);

==>

var _button = require('antd/lib/button');

ReactDOM.render(<div>
  <_button>xxxx</_button>
</div>);

这么说element-react还不支持按需加载, 只是兼容了webpack的tree shaking.

chenyihao2621023 commented 7 years ago

好的!谢谢您! 从vue开始 就特别喜欢贵团队的element-ui库 想问下,element-react 近期会有支持按需加载的计划吗

e1emeb0t commented 7 years ago

我试了下babel-plugin-import, 貌似还不兼容element-react, 所以我们需要开发一个兼容的版本, 近期可能没有计划.

chenyihao2621023 commented 7 years ago

好的 谢谢回答!

zyt-cloud commented 6 years ago

import Table from 'element-react/dist/npm/es6/src/table';

// import 'element-theme-default'

import 'element-theme-default/lib/table.css' import 'element-theme-default/lib/table-column.css'

这样可以实现按需引入

IEfucker commented 6 years ago

看了下node_modules/antd/es/index.js:

// this file is not used if use https://github.com/ant-design/babel-plugin-import
var ENV = process.env.NODE_ENV;
if (ENV !== 'production' && ENV !== 'test' && typeof console !== 'undefined' && console.warn && typeof window !== 'undefined') {
    console.warn('You are using a whole package of antd, ' + 'please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.');
}

babel-plugin-import这个插件起了至关重要的作用:

import { Button } from 'antd';

ReactDOM.render(<div>
  <Button>xxxx</Button>
</div>);

==>

var _button = require('antd/lib/button');

ReactDOM.render(<div>
  <_button>xxxx</_button>
</div>);

这么说element-react还不支持按需加载, 只是兼容了webpack的tree shaking.

感谢您的回答,有些疑问:所谓的按需加载和webpack的tree shaking有什么差别,为什么需要单独的babel插件才能做到按需加载(应该叫打包bundle吧)

pyl1995825 commented 5 years ago

我试了下babel-plugin-import, 貌似还不兼容element-react, 所以我们需要开发一个兼容的版本, 近期可能没有计划.

请问下还能兼容到element-react嘛