【问题标题】:Webpack 5 Polyfill Node util.TextDecoderWebpack 5 Polyfill 节点 util.TextDecoder
【发布时间】:2022-10-17 23:47:14
【问题描述】:

我已经在这里工作了好几天(如果你真的想要技术的话,几个月)。在有人将此标记为重复之前,不,我不想使用 ~530kb text-encoder 包,在线程 Polyfill for TextDecoder 上注明。此外,fastestsmallesttextencoderdecoder 似乎没有 TypeScript 类型并且不会编译。

我正在尝试使我的 VS Code 扩展与 VS Code 的 Web 环境兼容,这意味着我需要使用 Webpack 创建两个包(客户端和 Web 扩展略有不同)。

在我的一个源文件中,cheatsheet-content.ts

import { TextDecoder } from 'util';

// ...

const htmlDocument = await vscode.workspace.fs
    .readFile(
        vscode.Uri.joinPath(this._cheatsheetUri, 'cheatsheet.html')
    )
    .then((uint8array) => {
        const fileContent = new TextDecoder().decode(uint8array);  // <-- ERROR
        return parse(fileContent.toString());
    });

我收到错误消息(仅在作为 Web 扩展运行时):TypeError: util_1.TextDecoder is not a constructor

这是我的webpack.config.ts 文件:

/// <reference types="node" />

import * as path from 'node:path';
import { Configuration, ProvidePlugin } from 'webpack';

// eslint-disable-next-line unicorn/prefer-module
const projectRoot = __dirname;

const nodeConfig: Configuration = {
    // VS Code client extensions run in Node context. See: https://webpack.js.org/configuration/node/
    target: 'node',
    // Leaves the source code as close as possible to the original (when packaging we set this to 'production')
    mode: 'none',
    // Entry point into extension (in package.json). See: https://webpack.js.org/configuration/entry-context/
    entry: {
        'extension.node': './src/extension.node.ts',
    },
    // Bundle output location. See: https://webpack.js.org/configuration/output/
    output: {
        filename: '[name].js',
        path: path.join(projectRoot, 'dist'),
        libraryTarget: 'commonjs',
        devtoolModuleFilenameTemplate: '../[resource-path]',
    },
    devtool: 'nosources-source-map',
    // Support reading TypeScript and JavaScript files. See: https://github.com/TypeStrong/ts-loader
    resolve: {
        extensions: ['.ts', '.js'],
        alias: {
            src: path.resolve(projectRoot, 'src'),
        },
    },
    // Modules that cannot be added through Webpack. See: https://webpack.js.org/configuration/externals/
    externals: {
        vscode: 'commonjs vscode', // ignored because 'vscode' module is created on the fly and doesn't really exist
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'ts-loader',
                    },
                ],
            },
        ],
    },
    performance: {
        hints: false,
    },
    infrastructureLogging: {
        level: 'log', // enables logging required for problem matchers
    },
};

const browserConfig: Configuration = {
    // extensions run in a webworker context
    ...nodeConfig,
    target: 'webworker',
    entry: {
        'extension.web': './src/extension.web.ts',
        // 'test/suite/index': './src/web/test/suite/index.ts',
    },
    resolve: {
        ...nodeConfig.resolve,
        mainFields: ['browser', 'module', 'main'], // look for `browser` entry point in imported node modules
        fallback: {
            // eslint-disable-next-line unicorn/prefer-module
            util: require.resolve('util'),  // <-- Isn't this supposed to fix my issue?
        },
    },
    plugins: [
        new ProvidePlugin({
            process: 'process/browser', // provide a shim for the global `process` variable
        }),
    ],
};

// eslint-disable-next-line unicorn/prefer-module
module.exports = [nodeConfig, browserConfig];

我原以为将util 添加到resolve.fallback 可以解决问题,但我想不是吗?

我也试过用node-polyfill-webpack-plugin,但是没用,还对esModuleInterop大做文章。

Permalink 到我的 GitHub 存储库获取完整上下文。如果您有兴趣自己运行代码:

  1. 克隆存储库
  2. 运行npm ci
  3. 转到运行和调试在 VS Code 中选择Run Web Extension 配置
  4. 打开命令面板并运行OpenSCAD: Open Cheatsheet 命令。

    除了非常混乱之外,我对 Webpack 知之甚少。任何人都可以提供任何指导吗?

【问题讨论】:

    标签: node.js typescript webpack


    【解决方案1】:

    事实证明,不需要 polyfill TextDecoder,因为它是 Node 16 和现代浏览器的全局变量的一部分。可以删除下面的导入语句,一切正常。

    // import { TextDecoder } from 'util';  // <-- REMOVE ME
    
    // ...
    
    const htmlDocument = await vscode.workspace.fs
        .readFile(
            vscode.Uri.joinPath(this._cheatsheetUri, 'cheatsheet.html')
        )
        .then((uint8array) => {
            const fileContent = new TextDecoder().decode(uint8array);
            return parse(fileContent.toString());
        });
    

    见:https://github.com/microsoft/vscode-discussions/discussions/165#discussioncomment-3880268

    【讨论】:

      猜你喜欢
      • 2021-09-20
      • 1970-01-01
      • 2021-04-29
      • 2021-08-06
      • 1970-01-01
      • 2022-06-28
      • 2022-07-26
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多