欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

探索webpack模塊及webpack3新特性

 更新時(shí)間:2017年09月18日 16:14:05   作者:小深刻的松鼠  
webpack是一個(gè)強(qiáng)大的模塊打包工具,在處理依賴、模塊上都很優(yōu)秀,本文從bundle.js文件分析出發(fā)去探索了不同模塊方案的加載機(jī)制,初步去理解webpack,并且對(duì)webpack3特性進(jìn)行闡述

本文從簡(jiǎn)單的例子入手,從打包文件去分析以下三個(gè)問(wèn)題:webpack打包文件是怎樣的?如何做到兼容各大模塊化方案的?webpack3帶來(lái)的新特性又是什么?

一個(gè)簡(jiǎn)單的例子

webpack配置

 // webpack.config.js
module.exports = {
 entry: './src/index.js',
 output: {
 filename: 'bundle.js',
 path: path.resolve(__dirname, 'dist')
 },
};

簡(jiǎn)單的js文件

 // src/index.js
 console.log('hello world');

webpack打包后的代碼

一看你就會(huì)想,我就一行代碼,你給我打包那么多???(黑人問(wèn)號(hào))

// dist/bundle.js
 /******/ (function(modules) { // webpackBootstrap
/******/  // The module cache
/******/  var installedModules = {};
/******/
/******/  // The require function
/******/  function __webpack_require__(moduleId) {
/******/
/******/   // Check if module is in cache
/******/   if(installedModules[moduleId]) {
/******/    return installedModules[moduleId].exports;
/******/   }
/******/   // Create a new module (and put it into the cache)
/******/   var module = installedModules[moduleId] = {
/******/    i: moduleId,
/******/    l: false,
/******/    exports: {}
/******/   };
/******/
/******/   // Execute the module function
/******/   modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/   // Flag the module as loaded
/******/   module.l = true;
/******/
/******/   // Return the exports of the module
/******/   return module.exports;
/******/  }
/******/
/******/
/******/  // expose the modules object (__webpack_modules__)
/******/  __webpack_require__.m = modules;
/******/
/******/  // expose the module cache
/******/  __webpack_require__.c = installedModules;
/******/
/******/  // define getter function for harmony exports
/******/  __webpack_require__.d = function(exports, name, getter) {
/******/   if(!__webpack_require__.o(exports, name)) {
/******/    Object.defineProperty(exports, name, {
/******/     configurable: false,
/******/     enumerable: true,
/******/     get: getter
/******/    });
/******/   }
/******/  };
/******/
/******/  // getDefaultExport function for compatibility with non-harmony modules
/******/  __webpack_require__.n = function(module) {
/******/   var getter = module && module.__esModule ?
/******/    function getDefault() { return module['default']; } :
/******/    function getModuleExports() { return module; };
/******/   __webpack_require__.d(getter, 'a', getter);
/******/   return getter;
/******/  };
/******/
/******/  // Object.prototype.hasOwnProperty.call
/******/  __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/  // __webpack_public_path__
/******/  __webpack_require__.p = "";
/******/
/******/  // Load entry module and return exports
/******/  return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
console.log('hello world');
/***/ })
/******/ ]);

我們來(lái)分析一下這部分代碼,先精簡(jiǎn)一下,其實(shí)整體就是一個(gè)自執(zhí)行函數(shù),然后傳入一個(gè)模塊數(shù)組

 (function(modules) { 
  //...
 })([function(module, exports) {
  //..
 }])

好了,傳入模塊數(shù)組做了什么(其實(shí)注釋都很明顯了,我只是大概翻譯一下)

 /******/ (function(modules) { // webpackBootstrap
/******/  // The module cache 緩存已經(jīng)load過(guò)的模塊
/******/  var installedModules = {};
/******/
/******/  // The require function 引用的函數(shù)
/******/  function __webpack_require__(moduleId) {
/******/
/******/   // Check if module is in cache 假如在緩存里就直接返回
/******/   if(installedModules[moduleId]) {
/******/    return installedModules[moduleId].exports;
/******/   }
/******/   // Create a new module (and put it into the cache) 構(gòu)造一個(gè)模塊并放入緩存
/******/   var module = installedModules[moduleId] = {
/******/    i: moduleId, //模塊id
/******/    l: false, // 是否已經(jīng)加載完畢
/******/    exports: {} // 對(duì)外暴露的內(nèi)容
/******/   };
/******/
/******/   // Execute the module function 傳入模塊參數(shù),并執(zhí)行模塊
/******/   modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/   // Flag the module as loaded 標(biāo)記模塊已經(jīng)加載完畢
/******/   module.l = true;
/******/
/******/   // Return the exports of the module 返回模塊暴露的內(nèi)容
/******/   return module.exports;
/******/  }
/******/
/******/
/******/  // expose the modules object (__webpack_modules__) 暴露模塊數(shù)組
/******/  __webpack_require__.m = modules;
/******/
/******/  // expose the module cache 暴露緩存數(shù)組
/******/  __webpack_require__.c = installedModules;
/******/
/******/  // define getter function for harmony exports 為ES6 exports定義getter
/******/  __webpack_require__.d = function(exports, name, getter) {
/******/   if(!__webpack_require__.o(exports, name)) { // 假如exports本身不含有name這個(gè)屬性
/******/    Object.defineProperty(exports, name, {
/******/     configurable: false,
/******/     enumerable: true,
/******/     get: getter
/******/    });
/******/   }
/******/  };
/******/
/******/  // getDefaultExport function for compatibility with non-harmony modules 解決ES module和Common js module的沖突,ES則返回module['default']
/******/  __webpack_require__.n = function(module) {
/******/   var getter = module && module.__esModule ?
/******/    function getDefault() { return module['default']; } :
/******/    function getModuleExports() { return module; };
/******/   __webpack_require__.d(getter, 'a', getter);
/******/   return getter;
/******/  };
/******/
/******/  // Object.prototype.hasOwnProperty.call
/******/  __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/  // __webpack_public_path__ webpack配置下的公共路徑
/******/  __webpack_require__.p = "";
/******/
/******/  // Load entry module and return exports 最后執(zhí)行entry模塊并且返回它的暴露內(nèi)容
/******/  return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
console.log('hello world');
/***/ })
/******/ ]);

整體流程是怎樣的呢

  • 傳入module數(shù)組
  • 調(diào)用__webpack_require__(__webpack_require__.s = 0)

構(gòu)造module對(duì)象,放入緩存

調(diào)用module,傳入相應(yīng)參數(shù)modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); (這里exports會(huì)被函數(shù)內(nèi)部的東西修改)

標(biāo)記module對(duì)象已經(jīng)加載完畢

返回模塊暴露的內(nèi)容(注意到上面函數(shù)傳入了module.exports,可以對(duì)引用進(jìn)行修改)

  • 模塊函數(shù)中傳入module, module.exports, __webpack_require__
  • 執(zhí)行過(guò)程中通過(guò)對(duì)上面三者的引用修改,完成變量暴露和引用

webpack模塊機(jī)制是怎樣的

我們可以去官網(wǎng)看下webpack模塊

doc.webpack-china.org/concepts/mo…

webpack 模塊能夠以各種方式表達(dá)它們的依賴關(guān)系,幾個(gè)例子如下:

  • ES2015 import 語(yǔ)句
  • CommonJS require() 語(yǔ)句
  • AMD define 和 require 語(yǔ)句
  • css/sass/less 文件中的 @import 語(yǔ)句。
  • 樣式(url(...))或 HTML 文件()中的圖片鏈接(image url)

強(qiáng)大的webpack模塊可以兼容各種模塊化方案,并且無(wú)侵入性(non-opinionated)

我們可以再編寫(xiě)例子一探究竟

CommonJS

修改src/index.js

var cj = require('./cj.js');
console.log('hello world');
cj();

新增src/cj.js,保持前面例子其他不變

// src/cj.js
function a() {
 console.log("CommonJS");
}
module.exports = a;

再次運(yùn)行webpack

/******/ (function(modules) { // webpackBootstrap
 //... 省略代碼
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
let cj = __webpack_require__(1);
console.log('hello world');
cj();
/***/ }),
/* 1 */
/***/ (function(module, exports) {
function a() {
 console.log("CommonJS");
}
module.exports = a;
/***/ })
/******/ ]);

我們可以看到模塊數(shù)組多了個(gè)引入的文件,然后index.js模塊函數(shù)多了個(gè)參數(shù)__webpack_require__,去引用文件(__webpack_require__在上一節(jié)有介紹),整體上就是依賴的模塊修改了module.exports,然后主模塊執(zhí)行依賴模塊,獲取exports即可

ES2015 import

新增src/es.js

// src/es.js
export default function b() {
 console.log('ES Modules');
}

修改src/index.js

// src/index.js
import es from './es.js';
console.log('hello world');
es();
webpack.config.js不變,執(zhí)行webpack
/******/ (function(modules) { // webpackBootstrap
// ... 省略代碼
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__es_js__ = __webpack_require__(1);
console.log('hello world');
Object(__WEBPACK_IMPORTED_MODULE_0__es_js__["a" /* default */])();
/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (immutable) */ __webpack_exports__["a"] = b;
function b() {
 console.log('ES Modules');
}
/***/ })
/******/ ]);

我們可以看到它們都變成了嚴(yán)格模式,webpack自動(dòng)采用的

表現(xiàn)其實(shí)跟CommonJS相似,也是傳入export然后修改,在主模塊再require進(jìn)來(lái),

我們可以看到這個(gè)

Object.defineProperty(__webpack_exports__, "__esModule", { value: true });

這個(gè)干嘛用的?其實(shí)就是標(biāo)記當(dāng)前的exports是es模塊,還記得之前的__webpack_require__.n嗎,我們?cè)倌贸鰜?lái)看看

/******/  // getDefaultExport function for compatibility with non-harmony modules 解決ES module和Common js module的沖突,ES則返回module['default']
/******/  __webpack_require__.n = function(module) {
/******/   var getter = module && module.__esModule ?
/******/    function getDefault() { return module['default']; } :
/******/    function getModuleExports() { return module; };
/******/   __webpack_require__.d(getter, 'a', getter);
/******/   return getter;
/******/  };

為了避免跟非ES Modules沖突?沖突在哪里呢?

其實(shí)這部分如果你看到babel轉(zhuǎn)換ES Modules源碼就知道了,為了兼容模塊,會(huì)把ES Modules直接掛在exports.default上,然后加上__esModule屬性,引入的時(shí)候判斷一次是否是轉(zhuǎn)換模塊,是則引入module['default'],不是則引入module

我們?cè)俣嘁霂讉€(gè)ES Modules看看效果

// src/es.js
export function es() {
 console.log('ES Modules');
}
export function esTwo() {
 console.log('ES Modules Two');
}
export function esThree() {
 console.log('ES Modules Three');
}
export function esFour() {
 console.log('ES Modules Four');
}

我們多引入esTwo和esFour,但是不使用esFour

// src/index.js
import { es, esTwo, esFour} from './es.js';
console.log('hello world');
es();
esTwo();

得出

/******/ (function(modules) { // webpackBootstrap
// ...
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__es_js__ = __webpack_require__(1);
console.log('hello world');
Object(__WEBPACK_IMPORTED_MODULE_0__es_js__["a" /* es */])();
Object(__WEBPACK_IMPORTED_MODULE_0__es_js__["b" /* esTwo */])();
/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (immutable) */ __webpack_exports__["a"] = es;
/* harmony export (immutable) */ __webpack_exports__["b"] = esTwo;
/* unused harmony export esThree */
/* unused harmony export esFour */
function es() {
 console.log('ES Modules');
}
function esTwo() {
 console.log('ES Modules Two');
}
function esThree() {
 console.log('ES Modules Three');
}
function esFour() {
 console.log('ES Modules Four');
}
/***/ })
/******/ ]);

嗯嗯其實(shí)跟前面是一樣的,舉出這個(gè)例子重點(diǎn)在哪里呢,有沒(méi)有注意到注釋中

/* unused harmony export esThree */
/* unused harmony export esFour */

esThree是我們沒(méi)有引入的模塊,esFour是我們引用但是沒(méi)有使用的模塊,webpack均對(duì)它們做了unused的標(biāo)記,其實(shí)這個(gè)如果你使用了webpack插件uglify,通過(guò)標(biāo)記,就會(huì)把esThree和esFour這兩個(gè)未使用的代碼消除(其實(shí)它就是tree-shaking)

AMD

我們?cè)賮?lái)看看webpack怎么支持AMD

新增src/amd.js

// src/amd.js
define([
],function(){
 return {
  amd:function(){
   console.log('AMD');
  }
 };
});

修改index.js

// src/index.js
define([
 './amd.js'
],function(amdModule){
 amdModule.amd();
});

得到

/******/ (function(modules) { // webpackBootstrap
// ... 省略代碼
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
 __webpack_require__(1)
], __WEBPACK_AMD_DEFINE_RESULT__ = function(amdModule){
 amdModule.amd();
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
    __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
], __WEBPACK_AMD_DEFINE_RESULT__ = function(){
 return {
  amd:function(){
   console.log('AMD');
  }
 };
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
    __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/***/ })
/******/ ]);

先看amd.js整理一下代碼

function(module, exports, __webpack_require__) {
 var __WEBPACK_AMD_DEFINE_ARRAY__,
  __WEBPACK_AMD_DEFINE_RESULT__;
 !(
  __WEBPACK_AMD_DEFINE_ARRAY__ = [],
  __WEBPACK_AMD_DEFINE_RESULT__ = function() {
   return {
    amd: function() {
     console.log('AMD');
    }
   };
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
  __WEBPACK_AMD_DEFINE_RESULT__ !== undefined &&
  (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
 );
})

簡(jiǎn)單來(lái)講收集define Array然后置入返回函數(shù),根據(jù)參數(shù)獲取依賴

apply對(duì)數(shù)組拆解成一個(gè)一個(gè)參數(shù)

再看index.js模塊部分

function(module, exports, __webpack_require__) {
 var __WEBPACK_AMD_DEFINE_ARRAY__,
  __WEBPACK_AMD_DEFINE_RESULT__;
 !(
  __WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)],
  __WEBPACK_AMD_DEFINE_RESULT__ = function(amdModule) {
    amdModule.amd();
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
  __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && 
  (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
 );
}

其實(shí)就是引入了amd.js暴露的{amd:[Function: amd]}

css/image?

css和image也可以成為webpack的模塊,這是令人震驚的,這就不能通過(guò)普通的hack commonjs或者函數(shù)調(diào)用簡(jiǎn)單去調(diào)用了,這就是anything to JS,它就需要借助webpack loader去實(shí)現(xiàn)了

像css就是轉(zhuǎn)換成一段js代碼,通過(guò)處理,調(diào)用時(shí)就是可以用js將這段css插入到style中,image也類(lèi)似,這部分就不詳細(xì)闡述了,有興趣的讀者可以深入去研究

webpack3新特性

我們可以再順便看下webpack3新特性的表現(xiàn)

具體可以看這里medium.com/webpack/web…

Scope Hoisting

我們可以發(fā)現(xiàn)模塊數(shù)組是一個(gè)一個(gè)獨(dú)立的函數(shù)然后閉包引用webpack主函數(shù)的相應(yīng)內(nèi)容,每個(gè)模塊都是獨(dú)立的,然后帶來(lái)的結(jié)果是在瀏覽器中執(zhí)行速度變慢,然后webpack3學(xué)習(xí)了Closure Compiler和RollupJS這兩個(gè)工具,連接所有閉包到一個(gè)閉包里,放入一個(gè)函數(shù),讓執(zhí)行速度更快,并且整體代碼體積也會(huì)有所縮小

我們可以實(shí)際看一下效果(要注意的是這個(gè)特性只支持ES Modules,是不支持CommonJs和AMD的)

使用上面的例子,配置webpack.config.js,增加new webpack.optimize.ModuleConcatenationPlugin()

const path = require('path');
const webpack = require('webpack');
module.exports = {
 entry: './src/index.js',
 output: {
 filename: 'bundle.js',
 path: path.resolve(__dirname, 'dist')
 },
 module: {
 },
 plugins: [
 new webpack.optimize.ModuleConcatenationPlugin(),
 ]
};

打包

/******/ (function(modules) { // webpackBootstrap
// ... 省略代碼
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
// CONCATENATED MODULE: ./src/es.js
function es() {
 console.log('ES Modules');
}
function esTwo() {
 console.log('ES Modules Two');
}
function esThree() {
 console.log('ES Modules Three');
}
function esFour() {
 console.log('ES Modules Four');
}
// CONCATENATED MODULE: ./src/index.js
// src/index.js
console.log('hello world');
es();
/***/ })
/******/ ]);

我們可以驚喜的發(fā)現(xiàn)沒(méi)有什么require了,它們拼接成了一個(gè)函數(shù),good!😃

Magic Comments

code splitting是webpack一個(gè)重點(diǎn)特性之一,涉及到要?jiǎng)討B(tài)引入的時(shí)候,webpack可以使用 require.ensure去實(shí)現(xiàn),后來(lái)webpack2支持使用了符合 ECMAScript 提案 的 import() 語(yǔ)法,但是它有個(gè)不足之處,無(wú)法指定chunk的名稱chunkName,為了解決這個(gè)問(wèn)題,出現(xiàn)了Magic Comments,支持用注釋的方式去指定,如下

import(/* webpackChunkName: "my-chunk-name" */ 'module');

小結(jié)

webpack是一個(gè)強(qiáng)大的模塊打包工具,在處理依賴、模塊上都很優(yōu)秀,本文從bundle.js文件分析出發(fā)去探索了不同模塊方案的加載機(jī)制,初步去理解webpack,并且對(duì)webpack3特性進(jìn)行闡述,當(dāng)然,webpack還有很多地方需要去探索深究,敬請(qǐng)期待以后的文章吧~關(guān)于本文如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • JavaScript File API實(shí)現(xiàn)文件上傳預(yù)覽

    JavaScript File API實(shí)現(xiàn)文件上傳預(yù)覽

    這篇文章主要為大家介紹了JavaScript File API實(shí)現(xiàn)文件上傳預(yù)覽,F(xiàn)ile API將極大地方便 Web 端的文件上傳等操作,本文將介紹 File API的概況,并用兩個(gè)實(shí)例展示File API的應(yīng)用,感興趣的小伙伴們可以參考一下
    2016-02-02
  • javascript獲取select標(biāo)簽選中的值

    javascript獲取select標(biāo)簽選中的值

    這篇文章主要介紹javascript獲取select標(biāo)簽選中的值方法,比較實(shí)用,需要的朋友可以參考下。
    2016-06-06
  • js實(shí)現(xiàn)樓層滾動(dòng)效果

    js實(shí)現(xiàn)樓層滾動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)樓層滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • javascript中setTimeout的問(wèn)題解決方法

    javascript中setTimeout的問(wèn)題解決方法

    這篇文章主要介紹了javascript中setTimeout的問(wèn)題以及對(duì)應(yīng)的解決方法,需要的朋友可以參考下
    2014-05-05
  • js實(shí)現(xiàn)前端跨域postMessage的具體使用

    js實(shí)現(xiàn)前端跨域postMessage的具體使用

    這篇文章主要介紹了js實(shí)現(xiàn)前端跨域postMessage的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • uni-app實(shí)現(xiàn)微信小程序長(zhǎng)按拍視頻功能

    uni-app實(shí)現(xiàn)微信小程序長(zhǎng)按拍視頻功能

    這篇文章主要為大家詳細(xì)介紹了uni-app實(shí)現(xiàn)微信小程序長(zhǎng)按拍視頻功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • JavaScript中的this原理及6種常見(jiàn)使用場(chǎng)景詳解

    JavaScript中的this原理及6種常見(jiàn)使用場(chǎng)景詳解

    這篇文章主要介紹了JavaScript中的this原理及6種常見(jiàn)使用場(chǎng)景詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • JavaScript利用生成器函數(shù)實(shí)現(xiàn)優(yōu)雅處理異步任務(wù)流

    JavaScript利用生成器函數(shù)實(shí)現(xiàn)優(yōu)雅處理異步任務(wù)流

    Generators?是?JavaScript?中的一種特殊函數(shù),它們可以暫停執(zhí)行并根據(jù)需要生成多個(gè)值,本文將詳細(xì)介紹?generators?的作用、用法以及與其他語(yǔ)言特性的配合使用,希望對(duì)大家有所幫助
    2023-07-07
  • javascript實(shí)現(xiàn)很浪漫的氣泡冒出特效

    javascript實(shí)現(xiàn)很浪漫的氣泡冒出特效

    這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)很浪漫的氣泡冒出特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-11-11
  • 前端在WebSocket中加入Token的解決方式

    前端在WebSocket中加入Token的解決方式

    這篇文章主要給大家介紹了關(guān)于前端在WebSocket中加入Token的解決方式,文中提供了3種解決方法,對(duì)大家學(xué)習(xí)或者使用WebSocket具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-10-10

最新評(píng)論