latest log

酩酊状態で書いたエンジニアポエムです。酩酊状態で読んでください。

eslint の async/await サポートと rollup の dynamic import サポート

github.com を update しました。

最新の eslint が async/await に対応し、

{
  "parserOptions": {
    "ecmaVersion":  2017
  }
}

最新の rollup がフラグ付きながら import() に対応しました。

$ rollup --experimentalDynamicImport

これで eslint + rollup な bundle 環境における ES2017 + import() 対応がほぼ出揃った感じになりました。

npm で公開されているパッケージも、徐々に ES Modules にマイグレーションしていく流れができてきました。

2018/06/28 追記

dynamic import はeslintが公式にはサポートしてないため、 .eslinttc に "parser": "babel-eslint" を追加し、$ npm i -D babel-eslint を追加することでエラーを消す事ができます。

examples

// a.js
export class Foo {
  async fetch() {
    return new Promise(async(resolve, reject) => {
      try {
        const url = `https://localhost`;
        const text = await(await fetch(url)).text();
        await import("./b.js");

        resolve(text);
      } catch(err) {
        reject(err);
      }
    });
  }
}

(async() => {
  const foo = new Foo();
  const html = await foo.fetch();
  alert(html);
})();
// b.js
alert("b.js");
<!-- index.html -->
<script type="module" src="a.js"></script>

.eslintrc

{
  "parser": "babel-eslint",
  "parserOptions": {
    "ecmaVersion":      2017,
    "sourceType":       "module"
  },
  "env": {
    "browser":          true,
    "node":             true,
    "es6":              true
  },
  "extends": [
    "eslint:recommended"
  ],
  "rules": {
    "strict":           [0],
    "no-new":           [0],
    "new-cap":          [0],
    "no-empty":         [0],
    "no-shadow":        [0],
    "camelcase":        [0],
    "key-spacing":      [0],
    "dot-notation":     [0],
    "comma-dangle":     [0],
    "no-console":       [0],
    "no-multi-str":     [0],
    "no-multi-spaces":  [0],
    "no-control-regex": [0],
    "no-unused-vars":   [1, { "vars": "all", "args": "after-used"} ],
    "no-underscore-dangle": [0],
    "no-use-before-define": [0],
    "no-inner-declarations": [0]
  },
  "globals": {
    "unescape":         false,
    "escape":           false,
    "google":           false
  }
}

package.json

{
  "name": "app",
  "version": "0.0.0",
  "description": "",
  "main": "a.js",
  "scripts": {
    "bundle": "npm run bundle:es6",
    "bundle:es6": "rollup -c .rollup.es6.js",
    "bundle:es5": "rollup -c .rollup.es5.js"
  },
  "repository": {
    "type": "git",
    "url": "..."
  },
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "babel-eslint": "^8.2.5",
    "babel-preset-es2015-rollup": "^3.0.0",
    "eslint": "^5.0.1",
    "execa": "^0.10.0",
    "npm-run-all": "^4.1.3",
    "request": "",
    "rollup": "^0.62.0",
    "rollup-plugin-babel": "^3.0.5",
    "rollup-plugin-buble": "^0.19.2",
    "rollup-plugin-cleanup": "^3.0.0-beta.1",
    "rollup-plugin-commonjs": "^9.1.3",
    "rollup-plugin-eslint": "^4.0.0",
    "rollup-plugin-license": "^0.6.0",
    "rollup-plugin-node-resolve": "^3.3.0",
    "rollup-watch": "^4.3.1",
  }
}

.rollup.es6.js

import path from "path";
import resolve from "rollup-plugin-node-resolve"; // resolve node_modules/index.js to ES6
import commonjs from "rollup-plugin-commonjs";    // convert CommonJS -> ES6
//import buble from "rollup-plugin-buble";          // convert ES6 -> ES5
import eslint from "rollup-plugin-eslint";        // ESLint
//import cleanup from "rollup-plugin-cleanup";      // clear comments and empty lines
import license from "rollup-plugin-license";      // add License header

// --- ES5/ES6/CommonJS/ESModules -> ES6 bundle ---
export default {
  format: "es",
  entry: "a.js",
  dest: "bundle.es6.js",
  plugins: [
    resolve({ jsnext: true }),
    commonjs(),
  //buble(), // ES6 -> ES5
    eslint({ configFile: path.resolve("./.eslintrc") }),
    //cleanup(),
    license({
      banner: "",
      //thirdParty: {
      //  output: path.join(__dirname, "dependencies.txt"),
      //  includePrivate: true, // Default is false.
      //},
    }),
  ],
  intro: "",
  outro: "",
  banner: "",
  footer: "",
}

これらのファイルを用意して、 $ npm run bundle を実行すると、以下の bundle.es6.js が生成されます。

bundle.es6.js

class Foo {
  async fetch() {
    return new Promise(async(resolve, reject) => {
      try {
        const url = `https://localhost`;
        const text = await(await fetch(url)).text();
        await Promise.resolve().then(function () { return b; });

        resolve(text);
      } catch(err) {
        reject(err);
      }
    });
  }
}

(async() => {
  const foo = new Foo();
  const html = await foo.fetch();
  alert(html);
})();

alert("b.js");

var b = /*#__PURE__*/Object.freeze({

});

export { Foo };