【问题标题】:How to import a library like moment.js into a web worker如何将像moment.js这样的库导入网络工作者
【发布时间】:2022-03-10 09:27:09
【问题描述】:

我可以将安装了 npm 的库导入到 web worker 中吗?

我需要将moment.js 库用于网络工作者。

通过npm安装到node_modules/moment目录

我已经在 worker.js 文件的顶部尝试过这个:

importScripts('/node_modules/moment/moment.js');

但我明白了

GET http://192.168.2.1:8100/node_modules/moment/moment.js 404 (Not Found)

【问题讨论】:

    标签: ionic3 angular5 momentjs node-modules web-worker


    【解决方案1】:

    是的,有可能,您可能已经在使用像 webpackparcel 这样的流行打包工具,但即使您不是,它仍然是可能的,尽管可能不是直接来自 node_modules

    带包裹

    main.js
    // relative path to the worker from current file
    const worker = new Worker('../utils/myWorker.js');
    
    myWorker.js
    // use import like you would in any other file
    import moment from 'moment';
    
    console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);
    

    使用 Webpack(作为入口)

    main.js
    // relative to the expected public path (have in mind any filename transforms like hashing)
    const worker = new Worker('myWorker.bundle.js');
    
    myWorker.js
    // use import like you would in any other file
    import moment from 'moment';
    
    console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);
    

    webpack.config.js

    {
      entry: {
        main: './src/app/main.js'
        worker: './src/utils/myWorker.js',
      },
      output: {
        path: `${ROOT_PATH}/public`,
        filename: '[name].bundle.js',
      }
    }
    

    使用 Webpack (worker-loader)

    安装加载器

    main.js
    // relative path to the worker from current file
    import Worker from '../utils/myWorker.worker.js';
    
    const worker = new Worker();
    
    myWorker.worker.js
    // use import like you would in any other file
    import moment from 'moment';
    
    console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);
    

    webpack.config.js

    {
      module: {
        rules: [
          {
            test: /\.worker\.js$/,
            use: { loader: 'worker-loader' }
          }
        ]
      }
    }
    

    使用 CRA (Create React App) (worker-loader) 内联加载器

    使用内联加载器

    main.js
    /* eslint-disable import/no-webpack-loader-syntax */
    import Worker from "worker-loader!./myWorker.worker.js";
    
    const worker = new Worker();
    
    myWorker.worker.js
    // use import like you would in any other file
    import moment from 'moment';
    
    console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);
    

    您始终可以从 CDN 导入库

    myWorker.js
    importScripts('//cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js');
    
    console.log(`From worker: worker started at ${moment().format('HH:mm:ss')}`);
    

    其他捆绑程序

    • 出于安全原因,Web 工作人员不能从父文件夹importScripts
    • node_modules 文件夹通常位于项目的根目录,因此您无法使用importScripts 访问它
    • 需要配置捆绑程序,以便内容可以别名或复制到工作人员可以访问的位置

    AngularCLI、Ionic、CRA

    对于使用 webpack 作为打包器的项目,只要您可以访问 webpack 配置并对其进行自定义,就可以调整 2 个 webpack 解决方案。 如果您无法访问配置 (CRA),您可以使用“With CRA”示例中的内联加载程序

    “Webpack (as entry)”的例子其实是从Angular CLI generated app with Web Workers借来的

    • 它解释了如何使用 Web Worker 修改设置以引导 Angular
    • 它也被称为 Ionic 项目的网络工作者解决方案

    TypeScript 说明

    {
      "extends": "../generic-tsconfig.json",
      "compilerOptions": {
        "lib": ["esnext", "webworker"],
      }
    }
    

    【讨论】:

    • 对 webpack 都进行了尝试,但都没有成功。对于入门版本,捆绑文件从未生成,我无法对工人做任何事情。对于web-worker,它表示Attempted import error: './myWorker.worker.js' does not contain a default export (imported as 'Worker').
    • 也许你的意思是worker-loader 没有web-worker?从错误消息看来,webpack.config.js 中的 worker-loader 配置可能存在问题 - 导入的文件 ./myWorker.worker.js 被视为常规 js 导入,它没有通过 worker-loader 加载,因此“否默认导出”错误。您可以尝试内联加载器(它应该具有最高优先级) - import Worker from "worker-loader!./myWorker.worker.js"; - 如果这可行,则说明加载器的 webpack 配置有问题。 npmjs.com/package/worker-loader
    • 我试过这个并得到:Line 5:1: Unexpected '!' in 'worker-loader!./myWorker.worker.js'. Do not use import syntax to configure webpack loaders import/no-webpack-loader-syntax
    • 然后,我将这一行放在文件的顶部:/* eslint import/no-webpack-loader-syntax: off */ 它似乎工作
    【解决方案2】:

    截至 2020 年 8 月 12 日。 通过执行这些步骤,我已经成功地将 npm 模块与 CloudFlare Workers 一起使用。

    创建新项目:

    wrangler generate your-project
    cd your-project
    

    设置 'wrangler.toml' 以使用 webpack:

    name = "your-project"
    type = "webpack"
    account_id = "your-account-id"
    workers_dev = true
    route = ""
    zone_id = ""
    

    将你的 npm 模块导入 index.js 文件: 例如。

    const qr = require('qr-image')
    

    在终端/cmd:

    wrangler publish
    

    它会自动创建使用 webpack 打包的 worker。 现在它应该可以工作了。

    希望这对某人有所帮助,在谷歌上找了很长时间,然后决定尝试教程并找到了这个!

    【讨论】:

      【解决方案3】:

      从 webpack 5 开始,您可以使用 web worker 并导入库,而无需使用 worker-loader 或任何捆绑器 以简单的方式 如上所述 here

      我设法以同样的方式运行我的网络工作者并导入库。

      在你要导入web worker的文件中

      // here ./deep-thought.js is the path to the web worker
      
      const worker = new Worker(new URL('./deep-thought.js', import.meta.url));
      
      worker.postMessage({
        question:
          'The Answer to the Ultimate Question of Life, The Universe, and Everything.',
      });
      worker.onmessage = ({ data: { answer } }) => {
        console.log(answer);
      };
      

      在网络工作者文件中,

      // just to show it supports importing files into web worker in generic way
      
      import JSONstream from 'JSONStream';
      
       self.onmessage = function (e) {
         // worker code inside
      
         // just to show it supports importing and using files into web worker in generic way
      
         const jsonParser = JSONstream.parse();
       }
      

      【讨论】:

        猜你喜欢
        • 2021-04-13
        • 2019-10-29
        • 1970-01-01
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多