Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

atool-build 1.0 开发思路 #278

Open
soda-x opened this issue May 24, 2017 · 0 comments
Open

atool-build 1.0 开发思路 #278

soda-x opened this issue May 24, 2017 · 0 comments
Assignees
Milestone

Comments

@soda-x
Copy link

soda-x commented May 24, 2017

0.x.x 的做法

atool-build 最大的特点是基于 webpack.config.js 后强大的可扩展性。

但这灵活性的背后暴露的问题有:

  • 中性有限的内置配置并不能支撑现有的 80% 以上的业务,这可以在 所有业务方构建配置统计 中能体现出来。

  • 基于 webpack.config.js 的方式,修改内置配置并不是一件容易的事儿,如需求去除 common 逻辑

    webpackConfig.plugins.some(function(plugin, i){
      if(plugin instanceof webpack.optimize.CommonsChunkPlugin) {
        webpackConfig.plugins.splice(i, 1);
    
        return true;
      }
    });
  • 基于 webpack.config.js 的方式,让构建主体 atool-build 本身变得难以维护,因为这种方式强依赖主体的实现,如针对 antd-mobile 新增 svg-sprite-loader

    webpackConfig.module.loaders.forEach(function(loader) {
      if (loader.test && typeof loader.test.test === 'function' && loader.test.test('.svg')) {
        loader.exclude = svgDirs;
      }
    });
    
    webpackConfig.module.loaders.unshift({
      test: /\.(svg)$/i,
      loader: 'svg-sprite',
      include: svgDirs,
    });
  • 一些专有业务领域并没有沉淀最佳实践

    • html 以及 assets 的动态化生成
    • 智能化的 external
    • 深度缓存
    • pwa 资源处理
    • tree shaking
    • vendor
    • browser
    • 动态别名
    • boost performance
    • webpack 配置数组 (应用场景多语言等)
  • 基于以上的一些原因,atool-build 作为构建主体并不能非常好的收敛,同时由于 webpack.config.js 是独立散落在每个业务中的,如果一旦涉及一个业务 bu 配置层的更新,那么就要挨个找对应的同学升级,而往往这一类人为通知效果并不明显。

针对 dora,最大的特点是 koa 中间件的方式,让功能细粒度化

  • 调试方案过于零散,维护成本较大

1.0 的服务原则

经过上千个业务项目的统计在 1.0 中我们会涵盖满足 95% 以上的业务方。

ref:

1.0 中我们的原则是:

  • 不支持内置通用性的 Loader 和 Plugin 的替换或者删除,比如业界处理 sass 的处理已经有非常成熟的 sass-loader 那么我们就不支持你使用 sass-xx-loader 等这一类非常规 loader,还有我们处理 less 文件会根据开发者运行环境自行应用 extractTextPlugin, 以及 style-loader、css-loader、postcss-loader、less-loader,我们支持你改其中的参数,但是并不支持你替换其中任何一个 loader;
  • 不暴露内置的的 webpack 以及 loader 和 plugin;
  • 有限度支持扩展,新增非内置的 plugin(包含 babel) 和 loader,这样做一方面提升一定的灵活性,另外一方面,能让整体的构建能最大程度的保持收敛和稳定。

1.0 构建工具架构图

new_atool_1.png

1.0 构建工具架构图讲解

在 1.0 中我们最大的变更在于抹掉了 webpack.config.js 这种灵活的方式,取而代之的是我们提供了语义化的配置,即使用一个较能说明含义的单词来说明某个功能。目前规划下来看,落实到具体配置的应该是在 40 个左右。

用户层: 在这一层用户可以通过简单语义配置来描述想要的构建功能。由于 [email protected] 中我们尽量满足了 95% 的业务,所以在默认配置层面就尽量保持了中性,所以配置某个功能可能会需要涉及很多配置,解决这个问题我们会借鉴 eslint extends 的方式,所以我们会内置几套配置预设 - preset,比如 mobilePreset,pcPreset 等,这一层的配置会独立形成包。

所以用户层使用可能如下

{
   "extends": "atool-build/preset/mobilePreset",
   "common": false,
   "browser": ["iOS >=7", "android >=4"]
}

extends 的内容可以是某个扩展配置包(npm 包),也可以是 atool-build 的内建配置预设(npm 包)。

所以理论上用户层的配置也可以是个 npm 包。

extension 扩展层: 主要涵盖 2 点功能

  • 内建配置预设 preset:针对特定的业务场景的构建配置集, 该配置集即 preset 都是业务的最佳实践,比如 mobilePreset,pcPreset,当然随着特定业务肯定会出现注入 xxPreset 等。

  • merge:配置混合

transform 层: 把特定需要的 webpack 配置封装成一个函数,把 merge 后的配置集传入到函数中。在这种实现形式下,需要 webpack.dev.js 针对开发环境,webpack.production.js 针对生产环境,babel.config.js babel 配置,ts.config.js ts 配置,webpack.devServer.js webpack dev server 的配置(本期暂时不着重做)。

webpack.config.js、webpack 这两层其实是虚的,core 层最终突出的是一个 webpack 构建配置交由 webpack 做进一步处理。

bin: atool-build 提供的构建入口,同时会涵盖一些附属模块实现诸如工具升级提醒,自动 pr/mr,自定义配置 validator,性能检测等附加功能。

0.x.x vs 1.0 举例

去除内置 common 逻辑

0.x.x

webpackConfig.plugins.some(function(plugin, i){
  if(plugin instanceof webpack.optimize.CommonsChunkPlugin) {
    webpackConfig.plugins.splice(i, 1);

    return true;
  }
});

1.0

{
  "common": false
}

所有样式文件开启 css-module

0.x.x

webpackConfig.module.loaders.forEach(function(loader) {
  if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.less$') > -1) {
    loader.include = /node_modules/;
    loader.test = /\.less$/;
  }
  if (loader.test.toString() === '/\\.module\\.less$/') {
    loader.exclude = /node_modules/;
    loader.test = /\.less$/;
  }
  if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.css$') > -1) {
    loader.include = /node_modules/;
    loader.test = /\.css$/;
  }
  if (loader.test.toString() === '/\\.module\\.css$/') {
    loader.exclude = /node_modules/;
    loader.test = /\.css$/;
  }
});

1.0

{
  "css": {
    "module": true
  }
}

html 文件自动化生成,asstes 自动替换,external cdn 地址自动化注入

const HtmlWebpackPlugin = require('html-webpack-plugin');
webpackConfig.plugins.push(new HtmlWebpackPlugin({
  antBridgeVersion: '1.1.1',
  template: path.join(__dirname, '../src/common/entry.ejs'),
  entry: entry
}));

// ……………… 
// 没法玩啊,只能手动坑次坑次改

1.0

{
  "html": {
    "antBridgeVersion": "1.1.1",
    "template": "./src/entry.ejs",
    "cdn": true,
  },
  "external": true
}
@soda-x soda-x added this to the 1.0.0 milestone May 24, 2017
@soda-x soda-x self-assigned this May 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant