| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- import loggerFactory from '~/utils/logger';
- import { resolveFromRoot } from '~/utils/project-dir-utils';
- const { URL } = require('url');
- const urljoin = require('url-join');
- const { envUtils } = require('@growi/core');
- const cdnLocalScriptRoot = 'public/static/js/cdn';
- const cdnLocalScriptWebRoot = '/static/js/cdn';
- const cdnLocalStyleRoot = 'public/static/styles/cdn';
- const cdnLocalStyleWebRoot = '/static/styles/cdn';
- class CdnResourcesService {
- constructor() {
- this.logger = loggerFactory('growi:service:CdnResourcesService');
- this.loadManifests();
- }
- get noCdn() {
- return envUtils.toBoolean(process.env.NO_CDN);
- }
- loadManifests() {
- this.cdnManifests = require('^/resource/cdn-manifests');
- this.logger.debug('manifest data loaded : ', this.cdnManifests);
- }
- getScriptManifestByName(name) {
- const manifests = this.cdnManifests.js
- .filter((manifest) => { return manifest.name === name });
- return (manifests.length > 0) ? manifests[0] : null;
- }
- getStyleManifestByName(name) {
- const manifests = this.cdnManifests.style
- .filter((manifest) => { return manifest.name === name });
- return (manifests.length > 0) ? manifests[0] : null;
- }
- /**
- * download all resources from CDN and write to FS
- *
- * !! This method should be invoked only by /bin/download-cdn-resources when build client !!
- *
- * @param {CdnResourceDownloader} cdnResourceDownloader
- */
- async downloadAndWriteAll(cdnResourceDownloader) {
- const CdnResource = require('~/models/cdn-resource');
- const cdnScriptResources = this.cdnManifests.js.map((manifest) => {
- const outDir = resolveFromRoot(cdnLocalScriptRoot);
- return new CdnResource(manifest.name, manifest.url, outDir);
- });
- const cdnStyleResources = this.cdnManifests.style.map((manifest) => {
- const outDir = resolveFromRoot(cdnLocalStyleRoot);
- return new CdnResource(manifest.name, manifest.url, outDir);
- });
- const dlStylesOptions = {
- replaceUrl: {
- webroot: cdnLocalStyleWebRoot,
- },
- };
- return Promise.all([
- cdnResourceDownloader.downloadScripts(cdnScriptResources),
- cdnResourceDownloader.downloadStyles(cdnStyleResources, dlStylesOptions),
- ]);
- }
- /**
- * Generate script tag string
- *
- * @param {Object} manifest
- */
- generateScriptTag(manifest) {
- const attrs = [];
- const args = manifest.args || {};
- if (args.async) {
- attrs.push('async');
- }
- if (args.defer) {
- attrs.push('defer');
- }
- // TODO process integrity
- const url = this.noCdn
- ? `${urljoin(cdnLocalScriptWebRoot, manifest.name)}.js`
- : manifest.url;
- return `<script src="${url}" ${attrs.join(' ')}></script>`;
- }
- getScriptTagByName(name) {
- const manifest = this.getScriptManifestByName(name);
- return this.generateScriptTag(manifest);
- }
- getScriptTagsByGroup(group) {
- return this.cdnManifests.js
- .filter((manifest) => {
- return manifest.groups != null && manifest.groups.includes(group);
- })
- .map((manifest) => {
- return this.generateScriptTag(manifest);
- });
- }
- /**
- * Generate style tag string
- *
- * @param {Object} manifest
- */
- generateStyleTag(manifest) {
- const attrs = [];
- const args = manifest.args || {};
- if (args.async) {
- attrs.push('async');
- }
- if (args.defer) {
- attrs.push('defer');
- }
- // TODO process integrity
- const url = this.noCdn
- ? `${urljoin(cdnLocalStyleWebRoot, manifest.name)}.css`
- : manifest.url;
- return `<link rel="stylesheet" href="${url}" ${attrs.join(' ')}>`;
- }
- getStyleTagByName(name) {
- const manifest = this.getStyleManifestByName(name);
- return this.generateStyleTag(manifest);
- }
- getStyleTagsByGroup(group) {
- return this.cdnManifests.style
- .filter((manifest) => {
- return manifest.groups != null && manifest.groups.includes(group);
- })
- .map((manifest) => {
- return this.generateStyleTag(manifest);
- });
- }
- getHighlightJsStyleTag(styleName) {
- let manifest = this.getStyleManifestByName('highlight-theme-github');
- // replace style
- if (!this.noCdn) {
- const url = new URL(`${styleName}.css`, manifest.url); // resolve `${styleName}.css` from manifest.url
- // clone manifest
- manifest = Object.assign(manifest, { url: url.toString() });
- }
- return this.generateStyleTag(manifest);
- }
- }
- module.exports = CdnResourcesService;
|