瀏覽器如何實現import與require

一、瀏覽器是否支持import和require?

1.一、對require支持狀況

// add.js
module.exports = {
  add: function(num1, num2) {
    return num1 + num2
  }
}

// index.js
const { add } = require('./add')

document.getElementById("app").innerHTML = add(1, 2)

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
  <script src="./index.js"></script>
</body>
</html>

使用http-server啓動本地服務,訪問後報了以下錯誤:html

image.png

能夠明顯地得知瀏覽器不支持requirewebpack

1.二、對import支持狀況

// add.js
export const add = function(num1, num2) {
  return num1 + num2;
}

// index.js
import { add } from './add'

document.getElementById("app").innerHTML = add(1, 2)

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
  <script src="./index.js"></script>
</body>
</html>

啓動本地服務訪問會報以下錯誤:es6

image.png

所以,瀏覽器也不支持importweb

二、babel是如何處理import和require?

這裏使用babel命令行方式來編譯js,安裝相關依賴npm

cnpm i -D @babel/core @babel/cli @babel/preset-env

2.一、babel處理require

腳本json

// add.js
module.exports = {
  add: function(num1, num2) {
    return num1 + num2;
  }
}

// index.js
const { add } = require('./add')

module.exports = add

執行如下命令gulp

babel index.js -o build.js --presets=@babel/preset-env

構建後的代碼:瀏覽器

"use strict";

var _require = require('./add'),
    add = _require.add;

module.exports = add;

能夠看到babel對require是不作處理的,就加了一個嚴格模式babel

2.二、babel處理import

腳本app

// add.js
export const add = function(num1, num2) {
  return num1 + num2;
}

// index.js
import { add } from './add'

export default add

執行如下命令

babel index.js -o build.js --presets=@babel/preset-env

構建後的代碼:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _add = require("./add");

var _default = _add.add;
exports["default"] = _default;

能夠看到babel會對import進行處理,轉化爲commonjs規範。export default 被轉換成 exports["default"],同時還加了一個標記變量 __esModule 來描述這個 exports 是由 es6 export 轉換過來的。

三、webpack、gulp是如何處理import和require?

3.一、webpack如何處理import與require

安裝相關依賴

cnpm i -D webpack webpack-cli @babel/core @babel/preset-env

添加執行腳本

// package.json
scripts: {
    "build": "webpack --config webpack.config.js --mode production"
}

webpack.config.js

const path = require('path')

module.exports = {
  entry: './index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'build.js'
  }
}
3.1.一、對import處理

代碼:

// add.js
export const add = function(num1, num2) {
  return num1 + num2;
}

// index.js
import { add } from './add'

export default add

構建結果:

!(function (e) {
  var t = {};
  function r(n) {
    if (t[n]) return t[n].exports;
    var o = (t[n] = { i: n, l: !1, exports: {} });
    return e[n].call(o.exports, o, o.exports, r), (o.l = !0), o.exports;
  }
  (r.m = e),
    (r.c = t),
    (r.d = function (e, t, n) {
      r.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: n });
    }),
    (r.r = function (e) {
      "undefined" != typeof Symbol &&
        Symbol.toStringTag &&
        Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }),
        Object.defineProperty(e, "__esModule", { value: !0 });
    }),
    (r.t = function (e, t) {
      if ((1 & t && (e = r(e)), 8 & t)) return e;
      if (4 & t && "object" == typeof e && e && e.__esModule) return e;
      var n = Object.create(null);
      if (
        (r.r(n),
        Object.defineProperty(n, "default", { enumerable: !0, value: e }),
        2 & t && "string" != typeof e)
      )
        for (var o in e)
          r.d(
            n,
            o,
            function (t) {
              return e[t];
            }.bind(null, o)
          );
      return n;
    }),
    (r.n = function (e) {
      var t =
        e && e.__esModule
          ? function () {
              return e.default;
            }
          : function () {
              return e;
            };
      return r.d(t, "a", t), t;
    }),
    (r.o = function (e, t) {
      return Object.prototype.hasOwnProperty.call(e, t);
    }),
    (r.p = ""),
    r((r.s = 0));
})([
  function (e, t, r) {
    "use strict";
    r.r(t);
    t.default = function (e, t) {
      return e + t;
    };
  },
]);
3.1.二、對require處理

代碼:

// add.js
module.exports = {
  add: function(num1, num2) {
    return num1 + num2;
  }
}

// index.js
const { add } = require('./add')

module.exports = add

構建結果

!(function (e) {
  var t = {};
  function n(r) {
    if (t[r]) return t[r].exports;
    var o = (t[r] = { i: r, l: !1, exports: {} });
    return e[r].call(o.exports, o, o.exports, n), (o.l = !0), o.exports;
  }
  (n.m = e),
    (n.c = t),
    (n.d = function (e, t, r) {
      n.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r });
    }),
    (n.r = function (e) {
      "undefined" != typeof Symbol &&
        Symbol.toStringTag &&
        Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }),
        Object.defineProperty(e, "__esModule", { value: !0 });
    }),
    (n.t = function (e, t) {
      if ((1 & t && (e = n(e)), 8 & t)) return e;
      if (4 & t && "object" == typeof e && e && e.__esModule) return e;
      var r = Object.create(null);
      if (
        (n.r(r),
        Object.defineProperty(r, "default", { enumerable: !0, value: e }),
        2 & t && "string" != typeof e)
      )
        for (var o in e)
          n.d(
            r,
            o,
            function (t) {
              return e[t];
            }.bind(null, o)
          );
      return r;
    }),
    (n.n = function (e) {
      var t =
        e && e.__esModule
          ? function () {
              return e.default;
            }
          : function () {
              return e;
            };
      return n.d(t, "a", t), t;
    }),
    (n.o = function (e, t) {
      return Object.prototype.hasOwnProperty.call(e, t);
    }),
    (n.p = ""),
    n((n.s = 0));
})([
  function (e, t, n) {
    const { add: r } = n(1);
    e.exports = r;
  },
  function (e, t) {
    e.exports = {
      add: function (e, t) {
        return e + t;
      },
    };
  },
]);

其實,從構建結果能夠看出webpack會對import和require進行處理,用原生js實現了這兩種引入方式。

3.一、gulp如何處理import與require

安裝相關依賴

cnpm i -D gulp gulp-babel @babel/core @babel/preset-env

gulpfile.js構建腳本

const gulp = require('gulp')
const babel = require('gulp-babel')

const script = function() {
  return gulp.src('./index.js')
    .pipe(babel({
      presets: ['@babel/preset-env']
    }))
    .pipe(gulp.dest('./dist'))
}

module.exports.build = script
3.1.一、處理import

構建結果

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _add = require("./add");

var _default = _add.add;
exports["default"] = _default;
3.1.二、處理require

構建結果

"use strict";

var _require = require('./add'),
    add = _require.add;

module.exports = add;

從構建結果能夠看出gulp僅僅會處理import,將import轉化爲commonjs規範,可是不會處理require。

四、總結

一、瀏覽器不支持import和require
二、webpack、bowserify構建工具會處理require,可是gulp不會
三、處理方式是使用原生js實現require

參考:
https://www.jianshu.com/p/547...

相關文章
相關標籤/搜索