Mar*_*rco 3 javascript typescript webpack blazor blazor-webassembly
我有一个 Blazor WebAssembly 应用程序,在其中我尝试使用 JSInterop 包含 TypeScript/javascript 代码,但当 Webpack 在构建期间创建 js 代码时,该代码会失败。
hello-world.js
在 my 中创建一个wwwroot
包含以下内容的简单文件时:
export function showAlertSimple() {
alert("hello world");
}
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法非常轻松地调用它:
export function showAlertSimple() {
alert("hello world");
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试对在不同位置创建的 typescript 文件执行相同操作,然后使用 webpack 将其编译为 ES6,将其放入同一文件夹中,blazor 将无法调用该方法:
./NpmJs/src/hello-world2.ts
export function showAlertFromWebPack() {
alert("Hello World from webpack");
}
Run Code Online (Sandbox Code Playgroud)
./NpmJs/webpack.config.js
module.exports = {
entry: {
helloworld2: './src/hello-world2.ts',
},
module: {
rules: [
{
test: /\.ts?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../../wwwroot/js'),
},
devtool: 'source-map'
};
Run Code Online (Sandbox Code Playgroud)
public class HelloWorld : JSModule
{
public HelloWorld(IJSRuntime js)
: base(js, "./js/hello-world.js")
{
}
public async Task ShowAlert() => await InvokeVoidAsync("showAlert");
}
Run Code Online (Sandbox Code Playgroud)
然后,这会在浏览器控制台中引发以下异常:
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Could not find 'showAlertFromWebPack' ('showAlertFromWebPack' was undefined).
Error: Could not find 'showAlertFromWebPack' ('showAlertFromWebPack' was undefined).
Run Code Online (Sandbox Code Playgroud)
文件本身已正确加载。我可以在源选项卡中看到它。
我在这里缺少什么?
为了完整起见,这里是 JSModule 类,我无耻地从 Steven Sanderson 在 github 上插入了它。(https://github.com/SteveSandersonMS/AudioBrowser/blob/dd7a03d93b4de5e97efb333f1120792ee48c70ba/MediaFilesAPI/Util/JSModule.cs#L7)
public abstract class JSModule : IAsyncDisposable
{
private readonly Task<IJSObjectReference> moduleTask;
// On construction, we start loading the JS module
protected JSModule(IJSRuntime js, string moduleUrl)
=> moduleTask = js.InvokeAsync<IJSObjectReference>("import", moduleUrl).AsTask();
// Methods for invoking exports from the module
protected async ValueTask InvokeVoidAsync(string identifier, params object[]? args)
=> await (await moduleTask).InvokeVoidAsync(identifier, args);
protected async ValueTask<T> InvokeAsync<T>(string identifier, params object[]? args)
=> await (await moduleTask).InvokeAsync<T>(identifier, args);
// On disposal, we release the JS module
public async ValueTask DisposeAsync()
=> await (await moduleTask).DisposeAsync();
}
Run Code Online (Sandbox Code Playgroud)
我找到了 2 个可行的解决方案。一种使用 webpack,另一种则放弃 webpack 并用vitejs替代。
使用webpack,我们需要启用experiments.outputModule
(https://webpack.js.org/configuration/experiments/#experimentsoutputmodule)并设置output.library.type
为module
(https://webpack.js.org/configuration/output/#outputlibrarytype):
最终的配置将如下所示:
module.exports = {
entry: {
helloworld2: './src/hello-world2.ts',
},
module: {
rules: [
{
test: /\.ts?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../../wwwroot/js'),
library: {
type: "module",
},
},
experiments: {
outputModule: true
},
devtool: 'source-map'
};
Run Code Online (Sandbox Code Playgroud)
使用vitejs vite.config.js,配置将如下所示:
import * as path from 'path';
import { defineConfig } from "vite";
export default defineConfig({
appType: 'mpa',
build: {
target: 'esnext',
outDir: '../wwwroot/js',
lib: {
entry: path.resolve(__dirname, './src/index.ts'),
name: "YourPackageName",
fileName: (format) => `your-package-name.${format}.js`,
},
}
});
Run Code Online (Sandbox Code Playgroud)
Vite 本身会生成 2 个文件:
your-package-name.es.js
your-package-name.umd.js
您需要链接/使用 blazor 内的 es 文件,然后就可以开始了。
归档时间: |
|
查看次数: |
514 次 |
最近记录: |