문자열 변수에서 모듈 가져오기
in memory 변수에서 JavaScript 모듈을 가져와야 합니다.이 작업은 시스템을 사용하여 수행할 수 있습니다.JS와 웹팩.
하지만 어디에서도 좋은 작업 사례나 문서를 찾을 수 없습니다.설명서에서는 대부분 .js 파일의 동적 가져오기에 대해 설명합니다.
기본적으로 아래와 같이 모듈을 가져와야 합니다.
let moduleData = "export function doSomething(string) { return string + '-done'; };"
//Need code to import that moduleData into memory
만약 누군가가 문서를 가리킬 수 있다면 그것은 좋을 것입니다.
제한 사항이 있습니다.import
외부 라이브러리를 사용하지 않고는 불가능하지 않더라도 수행하기 어렵게 만드는 구문.
가장 가까운 방법은 동적 가져오기 구문을 사용하는 것입니다.두 가지 예가 있습니다. 첫 번째 예는 제가 쓴 원본이고 두 번째 예는 현대화를 원하는 사용자가 편집한 것입니다.
원래의 것.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<script>
var moduleData = "export function hello() { alert('hello'); };";
var b64moduleData = "data:text/javascript;base64," + btoa(moduleData);
</script>
<script type="module">
async function doimport() {
const module = await import(b64moduleData);
module.hello();
}
doimport();
</script>
</body>
</html>
현대화된 것:
function doimport (str) {
if (globalThis.URL.createObjectURL) {
const blob = new Blob([str], { type: 'text/javascript' })
const url = URL.createObjectURL(blob)
const module = import(url)
URL.revokeObjectURL(url) // GC objectURLs
return module
}
const url = "data:text/javascript;base64," + btoa(moduleData)
return import(url)
}
var moduleData = "export function hello() { console.log('hello') }"
var blob = new Blob(["export function hello() { console.log('world') }"])
doimport(moduleData).then(mod => mod.hello())
// Works with ArrayBuffers, TypedArrays, DataViews, Blob/Files
// and strings too, that If URL.createObjectURL is supported.
doimport(blob).then(mod => mod.hello())
그러나 이는 가져오기 코드가 구성되는 방식에 일부 제한이 있으며, 이는 사용자가 필요로 하는 것과 정확하게 일치하지 않을 수도 있습니다.가장 간단한 해결책은 서버에서 모듈의 코드를 전송하여 보다 일반적인 구문을 사용하여 가져올 임시 스크립트를 생성하는 것입니다.
let moduleData = await import("data:text/javascript,export function doSomething(str) { return str + '-done'; }");
그리고 그것을 테스트하기 위해.
moduleData.doSomething('test');
사용할 nodejs 플래그 --experimental-modules 사용import ... from ...;
node --experimental-modules index.mjs
index.mjs:
import fs from 'fs';
let fileContents = "export function doSomething(string) { return string + '-done'; };"
let tempFileName = './.__temporaryFile.mjs';
fs.writeFileSync(tempFileName, fileContents);
console.log('Temporary mjs file was created!');
import(tempFileName)
.then((loadedModule) => loadedModule.doSomething('It Works!'))
.then(console.log)
자세한 내용은 여기를 참조하십시오.
작동 방식:
- 먼저 파일을 만듭니다.
fs.writeFileSync
- 그런 다음 모듈을 로드하기 위해 가져오기 방법의 약속을 사용합니다.
- pipe doIt Works!로 메서드 호출.
- 그런 다음 doSomething의 결과를 기록합니다.
크레딧: https://stackoverflow.com/a/45854500/3554534, https://v8.dev/dynamic-import, @Louis
노드 JS:
// Base64 encode is needed to handle line breaks without using ;
const { Module } = await import(`data:text/javascript;base64,${Buffer.from(`export class Module { demo() { console.log('Hello World!') } }`).toString(`base64`)}`)
let instance = new Module()
instance.demo() // Hello World!
구성 요소 및 모듈을 즉시 생성할 수 있습니다.하지만 현에서 온 것은 아닙니다.다음은 예입니다.
name = "Dynamic Module on Fly";
const tmpCmp = Component({
template:
'<span (click)="doSomething()" >generated on the fly: {{name}}</span>'
})(
class {
doSomething(string) {
console.log("log from function call");
return string + "-done";
}
}
);
const tmpModule = NgModule({ declarations: [tmpCmp] })(class {});
this._compiler.compileModuleAndAllComponentsAsync(tmpModule).then(factories => {
const f = factories.componentFactories[0];
const cmpRef = this.container.createComponent(f);
cmpRef.instance.name = "dynamic";
});
여기 스택 블리츠가 있습니다.
Feroz Ahmed 답변을 기반으로 다음은 socket.io 을 통해 서버에서 Vue 3 구성 요소를 동적으로 로드하는 구체적인 예입니다.
서버 측(노드 + socket.io )
socket.on('give-me-component', (data: any, callback: any) => {
const file = fs.readFileSync('path/to/js/file', 'utf-8');
const buffer = Buffer.from(file).toString('base64');
callback(`data:text/javascript;base64,${buf}`);
});
클라이언트 측(Vue 3 + socket.io -client)
socket.emit('give-me-component', null, async (data: any) => {
// Supposes that 'component' is, for example, 'ref({})' or 'shallowRef({})'
component.value = defineAsyncComponent(async () => {
const imp = await import(data);
// ... get the named export you're interested in, or default.
return imp['TheNamedExport_or_default'];
});
});
...
<template>
<component :is="component" />
</template>
이상한 이유로, 제안된 동적 방법은import()
- "data" URL을 입력하면 다음과 같은 오류가 발생합니다.TypeError: Invalid URL
을 끝내면npm
패키지 코드
동일한 "데이터" URLimport()
하지만 응용 프로그램 코드의 오류 없이 s.
이상하다.
const module = await import(`data:text/javascript;base64,${Buffer.from(functionCode).toString(`base64`)}`)
<script type="module">
import { myfun } from './myModule.js';
myfun();
</script>
/* myModule.js */
export function myfun() {
console.log('this is my module function');
}
언급URL : https://stackoverflow.com/questions/57121467/import-a-module-from-string-variable
'programing' 카테고리의 다른 글
엘마에서 이메일을 보내시겠습니까? (0) | 2023.06.15 |
---|---|
벡터에 고유한 값을 R로 나열 (0) | 2023.06.10 |
JPA 수준에서 잠긴 업데이트 건너뛰기에 대한 선택 (0) | 2023.06.10 |
data.table에서 키를 설정하는 목적은 무엇입니까? (0) | 2023.06.10 |
다른 모든 요청에 대한 Kubernetes Traefik 내부 서버 오류 (0) | 2023.06.10 |