Coder Social home page Coder Social logo

athm-fe / create-autofe-app Goto Github PK

View Code? Open in Web Editor NEW
31.0 5.0 7.0 1.19 MB

Recommended Tooling for AutoFE Development

Home Page: https://athm-fe.github.io/create-autofe-app/

JavaScript 76.77% HTML 13.55% CSS 6.53% Shell 0.83% TypeScript 1.02% SCSS 1.30%
gulp webpack autohome

create-autofe-app's Issues

import() 需要 webpack 的 publicPath 配置

有可能我们会需要 import()require.ensure 来动态加载 chunk,而 chunk 加载的路径是需用通过 webpack 的 publicPath 来解析的。
需要考虑下这个玩意儿。

关于 js 打包策略

背景:目前只有 js 压缩功能
目标:

  1. 使用 es6 的方式组织模块
  2. 能兼容现有的 js 压缩功能
  3. 配置简单,方便易用

打包时Eslint检测适当放宽

涉及引入第三方模块,现在的检测规则太严格,需要修改的东西太多。打包的时候建议Eslint规则改简单些。

2018 RoadMap

  1. js 打包策略是否需要调整,目前文件命名约定是否 ok ?
  2. es6 code 打包后,开发想要修改怎么办?
  3. 考虑引入 CSS 规范检查,参考 airbnb/css
  4. 扩展目录约定,不仅限于 src ,开启另一个模式:直接把项目根目录作为 src

未完待续...

统一规划自定义配置需求

无论是 webpack 还是 gulp 的各种插件,我们可能都希望有自定义配置需求。所以需要统一规划一下该方案。

目标:

  1. 配置要方便
  2. 不暴露太多配置项
  3. 提供一定的配置灵活性
  4. 过滤掉一些配置项,不允许自定义

ES特性以及Babel支持情况和方案梳理

当浏览器报告脚本错误时

先分析错误信息,找出是语法问题,还是 API 不支持。

如果是语法问题(还没有被 babel-preset-autofe-app 支持):

  • 请先查看是否有新版 babel-preset-autofe-app
  • 如果还是不行,请自行配置 babelrc
  • 或者提 Issue 要求我添加到 babel-preset-autofe-app

如果是 API 不支持,请自行提供 Polyfill,参考下文 Polyfill 策略

注意目前不建议使用如下内容:

  • Symbol 和 Iterator
  • Generator
  • Async/Await

如下内容可能有问题,需要小心(可以提供 Polyfill 搞定)

  • for..of ,依赖 Symbol 和 Iterator
  • string destructuring ,依赖 Symbol 和 Iterator,以及 Array.isArray
  • string spread ,依赖 Array.from ,以及 Array.isArray
  • import()/require.ensure() ,依赖 Promise 和 Function.prototype.bind
  • Object rest ,依赖 Array.prototype.indexOf
  • class extends ,依赖 Object.create

所以,如果要兼容 ie8 ,请使用 es5-shim+es5-sham 或者 babel-polyfill 。其它的,请自己根据情况处理。

另外,要兼容 ie8 的话,不要使用 ES6 Modules ,使用 CommonJS Modules 。

Polyfill 策略

babel-polyfill

省心省力,就是有点大,但是功能齐全

注意:一个页面只能引用一个 babel-polyfill ,所以不建议给每一个 entry 加上 babel-polyfill ,除非你能够保证每一个页面只引用一个 entry。

entry: {
  pageA: ['babel-polyfill', './pagea'],
  pageB: ['babel-polyfill', './pageb'],
  ...
},

建议修改为

entry: {
  vendor: 'babel-polyfill', // 或者自定义 ./polyfill
  pageA: './pagea',
  pageB: './pageb',
},

autofe-polyfill

提供必要的 Polyfill 内容:

  • es5-shimes5-sham for <= ie8
  • Object.assign, 使用 object-assign
  • Promise, 使用 es6-promise
  • Array.from, 提供对 string spread 的支持

该 Pollyfill 适用于使用 ES6+ 的语法,但是不使用 ES6+ 的 Built-ins(Map, Set 等) 和新 API 的情况。

额外引用(强烈推荐)

自己在页面中引用:

<script src="/path/to/json3.min.js"></script>
<script src="/path/to/es5-shim.min.js"></script>
<script src="/path/to/es5-sham.min.js"></script>
<script src="/path/to/es6-promise.auto.min.js"></script>
<script src="/path/to/custom-polyfills.js"></script>

或者这么搞:

polyfills.entry.js

require('es5-shim');
require('es5-shim/es5-sham');

Object.assign = require('object-assign');
require('es6-promise/auto');

index.html

<script src="polyfills.js"></script>

想用 old IEs: 678

  • JSON 不被 IE67 支持,如需要,建议单独引入,JSON2 或 JSON3
  • 关键字作为属性名,如下两个插件可以解决
    transform-es3-property-literals
    transform-es3-member-expression-literals
  • 很多需要 defineProperty 支持的特性在 IE8 不可用,所以一些插件开启了 loose 模式。但是还是有一些功能不可用,比如 ES6 Modules 。

webpack uglifyJsPlugin 配置

new webpack.optimize.UglifyJsPlugin({
    compress: {
        properties: false,
        warnings: false
    },
    output: {
        beautify: true,
        quote_keys: true
    },
    mangle: {
        screw_ie8: false
    },
    sourceMap: false
})

转换后代码依赖的一些 API

ES5 的 API

大多数能够提供 Polyfill

  • Function.prototype.bind
  • Array.isArray
  • Array.prototype.indexOf
  • Object.create
  • Object.getOwnPropertyDescriptor

但是 Object 相关的几个 API 没法完全 Polyfill

  • Object.defineProperty
  • Object.defineProperties
  • Object.getPrototypeOf
  • Object.freeze
require('es5-shim');
require('es5-shim/es5-sham');

一些ES6 的 build-ins

  • Symbol, prototype[Symbol.iterator],比如 Array destructuring, For Of
  • Promise,动态加载 chunk, async/await

一些 ES6 的新 API

  • Array.from
  • Object.assign 暂时不用,关闭了 transform-object-rest-spread 的 useBuiltIns

不好 Polyfill 的(不用担心,class 的 loose 模式不需要这些特性):

  • Object.setPrototypeOf
  • Object.prototype.__proto__

ES6 Modules vs CommonJS Modules

如果你不需要考虑支持 IE8 及一下,那么放心使用 ES6 Modules 。如果你真的需要支持 IE8,那么请使用 CommonJS Modules。

同样,动态加载 chunk 的 import()require.ensure() 也遵循这个道理(虽然,我们在常规页面开发中基本用不到这个)。

原因解析:因为 ES6 Modules 依赖 Object.defineProperty

class & extends

class 的实现依赖 ES5 的一些 API,这些 API 不被 IE8 所支持,并且无法很好的 Polyfill 。

更无语的是,extends 的实现依赖 setPrototypeOf__proto__ ,这两个特性在 IE 10 才有实现。虽然 babel 做了一些很巧妙的处理,使得我们能够实现类方法的 super 调用,但是无法做到类原型方法的 super 调用。

所以为了使用 class ,开启了相关插件的 loose 模式。这种模式下,仅仅需要提供 Object.create 的
Polyfill 即可。

// Transforms class properties, property and static
'transform-class-properties',
// For classes that have supers, the super class won’t resolve correctly.(IE10 and below)
// so enable loose mode
['transform-es2015-classes', {
  loose: true,
}],

下面这两个不要用,一般来说都用不到:

  • transform-proto-to-assign
  • transform-object-set-prototype-of-to-assign

babel-polyfill vs transform-runtime

babel-polyfill 优点

  • 配置简单,省心

babel-polyfill 缺点

  • 污染全局
  • 抢先执行
  • 很多 polyfill 用不到,文件太大

transform-runtime 优点:

  • 不污染全局
  • 按需使用
  • 可以解决 helpers 重复的问题
  • 可以通过设置 helperspolyfill 以及 regenerator 来决定需要什么功能

transform-runtime 的缺点:

  • 不能 polyfill 已经存在的 Built-ins,所以还需要自己解决这部分的 polyfills
  • 配置稍微麻烦一些,不过也更加灵活

所以在应用中可以综合使用,比如 babel-polyfill + transform-runtime 的 helpers 处理能力。
而在工具和库的开发中,就不能使用 babel-polyfill 了。

综合上面的分析结果,决定自己定制 polyfill ,详情见 autofe-polyfill

推荐如下配置(如果需要提供 regenerator-runtime 的话):

// Runtime transform
['transform-runtime', {
  helpers: false, // helpers 很鸡肋,开启后,打包代码反而变大
  polyfill: false,
  regenerator: true,
}],

Generator and Async/Await

目前建议不用 Generator、async/await ,老老实实用 Promise 就好。

如果一定要使用的话,请阅读下面的内容,并自行配置。

相关插件:

  • transform-regenerator, in preset-es2015
  • transform-async-to-generator, in preset-es2017
  • transform-async-generator-functions, in stage-3
  • regeneratorRuntime,由 babel-polyfill 或者 transform-runtime 提供。

generator 如果转为 ES5 代码,需要 regeneratorRuntime,而这个东东由 babel-polyfill 或者 transform-runtime 提供。

使用 transform-async-generator-functions

不使用 transform-regenerator 自带的 asyncGenerator to Generator

'transform-async-generator-functions',
['transform-regenerator', {
  asyncGenerators: false,
}],

使用 transform-async-to-generator

不使用 transform-regenerator 自带的 async to Generator

'transform-async-to-generator',
['transform-regenerator', {
  async: false,
}],

只使用 transform-regenerator

自动进行如下转换:

  1. asyncGenerator to Generator
  2. async to Generator
  3. Generator to regeneratorRuntime
'syntax-async-generators',
'transform-regenerator',

相当于

'syntax-async-generators',
['transform-regenerator', {
  asyncGenerators: true,
  async: true,
  generators: true,
}],

推荐

'transform-async-generator-functions',
'transform-async-to-generator',
['transform-regenerator', {
  asyncGenerators: false,
  async: false,
  generators: true,
}],

preset-es2015 默认关闭 asyncGeneratorsasync

[transformRegenerator, { async: false, asyncGenerators: false }],

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.