Поскольку вы упоминаете Moment. js, я сначала объясню, как его загрузить. Это можно сделать так, как вы это сделали, импортировав его в модуль вашего компонента, однако это приведет к большому размеру пакета, поскольку моментальный пакет npm предназначен не для браузеров, а для использования в проектах Node.js, где размер пакета не имеет значения Момент. js распространяет пакеты браузера внутри пакета. Итак, что вы можете сделать, это добавить задачу копирования в вашу цель вывода Stencil, чтобы скопировать node_modules/moment/min/moment.min.js
в каталог сборки:
// stencil.config.ts
import { Config } from '@stencil/core';
export const config: Config = {
namespace: 'my-app',
outputTargets: [
{
type: 'www',
copy: [
{
src: '../node_modules/moment/min/moment.min.js',
dest: 'lib/moment.min.js'
}
]
}
]
};
Затем, как вы уже пробовали с вашей библиотекой, вы можете загрузить этот скрипт в src/index.html
:
<script src="/lib/moment.min.js"></script>
Однако ваш проект Typescript еще не будет знать, что moment
доступно в глобальной области. Это легко решить, вы можете просто добавить файл декларации где-нибудь в вашем проекте, например src/global.d.ts
с содержимым
import _moment from 'moment';
declare global {
const moment: typeof _moment;
}
Для ваших тестовых файлов, которые работают в контексте Node.js, не контекст браузера, вы можете импортировать момент или также добавить moment
в глобальную область, создав файл (например, jest-setup-file.js
) с содержимым
global.moment = require('moment');
, а затем в stencil.config.ts
вы просто добавьте поле setupFilesAfterEnv
к testing
:
{
testing: {
setupFilesAfterEnv: ['<rootDir>/jest-setup-file.js']
}
}
Если вам не нужен скрипт во всем приложении, а только при загрузке указанного c компонента, он делает больше смысла загружать скрипт только из этого компонента. Самый простой способ сделать это - создать элемент script
и добавить его в DOM:
declare const MyLib: any; // assuming that `mylib.js` adds `MyLib` to the global scope
export class MyComp {
componentWillLoad() {
const src = "assets/js/mylib.js";
if (document.querySelector(`script[src="${src}"]`)) {
return; // already exists
}
const script = document.createElement('script');
script.src = src;
document.head.appendChild(script);
}
}
Скорее всего, ваш скрипт / библиотека также внесет переменную в глобальную область, так что вы необходимо снова сообщить Typescript, что можно сделать с помощью ключевого слова declare
, чтобы объявить, что переменная существует в глобальном контексте (см. https://www.typescriptlang.org/docs/handbook/declaration-files/by-example.html#global -variables ).
В качестве другого примера, вот помощник, который я написал для загрузки API карт Google:
export const importMapsApi = async () =>
new Promise<typeof google.maps>((resolve, reject) => {
if ('google' in window) {
return resolve(google.maps);
}
const script = document.createElement('script');
script.onload = () => resolve(google.maps);
script.onerror = reject;
script.src = `https://maps.googleapis.com/maps/api/js?key=${googleApiKey}&libraries=places`;
document.body.appendChild(script);
});
(тип google
происходит из пакета @types/googlemaps
)
Затем я могу использовать это как
const maps = await importMapsApi();
const service = new maps.DistanceMatrixService();