亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

WebAssembly應(yīng)用到前端工程(下)—— webpack和webassembly

RichardXG / 3251人閱讀

摘要:然而在當前以為主要編譯工具的實際工程應(yīng)用中依然存在問題。涉及到的技術(shù)主要為模塊機制插件編寫與插件編寫。使用可以參考或,歡迎。上一篇應(yīng)用到前端工程上模塊的編寫

在上一篇文章WebAssembly應(yīng)用到前端工程(上)—— webassembly模塊的編寫中,完成了@ne_fe/gis模塊的編寫與發(fā)布。然而webassembly在當前以webpack4為主要編譯工具的實際工程應(yīng)用中依然存在問題。

盡管webpack4新增了對wasm文件的編譯支持,在wasm模塊編寫完成之后將其與webpack結(jié)合的過程中發(fā)現(xiàn),wasm模塊無法被正確加載。在對@ne_fe/gis編譯輸出文件的檢查之后,有了新的解決方案 wasm-module-webpack-plugin。

出現(xiàn)的問題

直接在前端工程中引入@ne_fe/gis并使用的話,控制臺會輸出錯誤信息

index.js?558c:1 GET http://localhost:8080/gps.wasm 404 (Not Found)
Uncaught (in promise) TypeError: Incorrect response MIME type. Expected "application/wasm".

查看所引用的@ne_fe/gis/dist/index.js后發(fā)現(xiàn)這樣一句話

var Pn="undefined"!=typeof location?location.pathname.split("/"):[];Pn.pop(),(Cn?WebAssembly.instantiateStreaming(fetch(Pn.join("/")+"/gps.wasm"),o):fetch(Pn.join("/")+"/gps.wasm").then(e=>e.arrayBuffer()).then(e=>WebAssembly.instantiate(e,o)))

出錯原因時由于fetch直接從根路徑下直接獲取wasm文件,但文件并沒有生成或移動,webpack并不能處理fetch所加載的文件,最終導致wasm加載失敗。

babel

webpack不能處理js的fetch語句,導致了上面問題的出現(xiàn),那么只有一種方法能夠處理fetch語句,那就是babel。
下面來編寫一個babel插件處理fetch加載wasm的情況

// babel-plugin.js
module.exports = function() {
  return {
    visitor: {
      CallExpression(path, state) {
        if(path.node.callee.name === "fetch"){
          const argument = JSON.parse(JSON.stringify(path.node.arguments[0]));
          for (const i in argument.right) {
            if (i === "value" && argument.right[i].endsWith(".wasm")) {
             console.log("argument.right[ i ]", argument.right[ i ], "state.file.opts.filename", state.file.opts.filename);
            }
          }
        }
      },
    }
  }
};

在webpack中使用

// webpack.config.js
const path = require("path");
const BabelPlugin = require("./babel-plugin");
module.exports = {
  module: {
    rules: [
      ...
      {
        test: /.js$/,
        loader: "babel-loader",
        include: [ path.join(process.cwd(), "./node_modules/@ne_fe/gis") ],
        options: {
          plugins: [ BabelPlugin ],
        },
      },
      ...
    ],
  },
  plugins: [
    ...
  ],
};

啟動webpack進行編譯,控制臺輸出

argument.right[ i ] /gps.wasm 
state.file.opts.filename C:dir	est
ode_modules@ne_fegisdistindex.js

最終獲得了fetch所加載的wasm文件名與fetch語句所在文件。

webpack

在上一步中獲取到了fetch語句加載的wasm文件名與fetch語句所在文件。
為了將wasm文件輸出到webpack編譯結(jié)果中,需要添加webpack插件。經(jīng)修改之后,整個結(jié)合wasm與webpack的插件如下

// event-listener.js
const EventEmitter = require("events").EventEmitter;
class Events extends EventEmitter {
  constructor(prop) {
    super(prop);
    this.data = {};
  }
}
const events = new Events();
events.on("wasm", data => {
  if (!events.data[data.wasmRefFileName]) {
    events.data[data.wasmRefFileName] = {};
    events.data[data.wasmRefFileName][data.wasmRefPath] = data.wasmDir;
  } else {
    if (!events.data[data.wasmRefFileName][data.wasmRefPath]) {
      events.data[data.wasmRefFileName][data.wasmRefPath] = data.wasmDir;
    }
  }
});
module.exports = events;
// babel-plugin.js
const eventEmitter = require("./event-listener");
const pathInternal = require("path");
module.exports = function() {
  return {
    visitor: {
      CallExpression(path, state) {
        if(path.node.callee.name === "fetch"){
          const argument = JSON.parse(JSON.stringify(path.node.arguments[0]));
          for (const i in argument.right) {
            if (i === "value" && argument.right[i].endsWith(".wasm")) {
              eventEmitter.emit("wasm", {
                wasmRefPath: argument.right[i],
                wasmRefFileName: state.file.opts.filename,
                wasmDir: pathInternal.parse(state.file.opts.filename).dir,
              });
            }
          }
        }
      },
    }
  }
};
// webpack-plugin
const eventEmitter = require("./event-listener");
const path = require("path");

class WasmPlugin {
  apply(compiler) {
    compiler.plugin("emit", function(compilation, callback) {
      for (const i in eventEmitter.data) {
        for (const j in eventEmitter.data[i]) {
          const filePath = path.join(eventEmitter.data[ i ][ j ], "." + j);
          const content = compiler.inputFileSystem._readFileSync(filePath);
          const stat = compiler.inputFileSystem._statSync(filePath);
          const wasmRefPath = j;
          const wasmName = wasmRefPath.substring(1, wasmRefPath.length);
          compilation.assets[wasmName] = {
            size() {
              return stat.size;
            },
            source() {
              return content;
            },
          };
        }
      }
      callback();
    });
  }
}

module.exports = WasmPlugin;

event-listener的作用是為了保存babel-plugin中獲取到的wasm相關(guān)信息然后在webpack插件執(zhí)行的時候使用,webpack-plugin將獲取到的wasm文件輸出到正確路徑。

涉及到的技術(shù)主要為commonjs模塊機制、babel插件編寫與webpack插件編寫。

使用

可以參考wasm-module-webpack-plugin或@ne_fe/gis,歡迎start。

尾語

盡管webassembly的出現(xiàn)對前端開發(fā)高性能瀏覽器應(yīng)用有了重大的作用,webpack4也新增了對webassembly的支持,但是目前以webpack編譯為主的前端工程對webassembly的支持依然不友好,開發(fā)難度不小,希望以后有更好的解決方案。
?
?
上一篇:WebAssembly應(yīng)用到前端工程(上)—— webassembly模塊的編寫

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/105127.html

相關(guān)文章

  • WebAssembly應(yīng)用前端工程(上)—— webassembly模塊的編寫

    摘要:本文以這個模塊的開發(fā)過程梳理如何應(yīng)用到前端工程中。注使用完成開發(fā)至少需要基礎(chǔ)的編碼能力。具體其他信息可以參考上該模塊的。配置主要針對源碼文件,需要添加正確的進行處理。下一篇應(yīng)用到前端工程下和 前言 WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine...

    Mr_houzi 評論0 收藏0
  • 2018前端值得關(guān)注的技術(shù)

    摘要:年前端有哪些領(lǐng)域,技術(shù)值得關(guān)注,哪些技術(shù)會興起,哪些技術(shù)會沒落。自從谷歌提出后,就持續(xù)的獲得了業(yè)界的關(guān)注,熱度可見一斑。就在今年,谷歌也宣布將獲得與安卓原生應(yīng)用同等的待遇與權(quán)限。但是無論都值得關(guān)注。 1.前言 2017悄然過去,2018已經(jīng)來到。人在進步,技術(shù)在發(fā)展。2018年前端有哪些領(lǐng)域,技術(shù)值得關(guān)注,哪些技術(shù)會興起,哪些技術(shù)會沒落。下面就我個人的判斷進行一個預測判斷,希望能對大家...

    xiao7cn 評論0 收藏0
  • 2018前端值得關(guān)注的技術(shù)

    摘要:年前端有哪些領(lǐng)域,技術(shù)值得關(guān)注,哪些技術(shù)會興起,哪些技術(shù)會沒落。自從谷歌提出后,就持續(xù)的獲得了業(yè)界的關(guān)注,熱度可見一斑。就在今年,谷歌也宣布將獲得與安卓原生應(yīng)用同等的待遇與權(quán)限。但是無論都值得關(guān)注。 1.前言 2017悄然過去,2018已經(jīng)來到。人在進步,技術(shù)在發(fā)展。2018年前端有哪些領(lǐng)域,技術(shù)值得關(guān)注,哪些技術(shù)會興起,哪些技術(shù)會沒落。下面就我個人的判斷進行一個預測判斷,希望能對大家...

    用戶84 評論0 收藏0
  • 前端每周清單半年盤點之 WebAssembly

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。利用降低三倍加載速度自推出之后,很多開發(fā)者都開始嘗試在小型項目中實踐,不過尚缺大型真實案例比較。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點;分為新聞熱點、開發(fā)教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目...

    Alan 評論0 收藏0
  • 前端每周清單半年盤點之 JavaScript 篇

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。背后的故事本文是對于年之間世界發(fā)生的大事件的詳細介紹,闡述了從提出到角力到流產(chǎn)的前世今生。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點;分為新聞熱點、開發(fā)教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎...

    Vixb 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<