Switch to esm fully
parent
217337745a
commit
9cd2057cd8
|
@ -8,6 +8,7 @@
|
||||||
"node": "14.17.5"
|
"node": "14.17.5"
|
||||||
},
|
},
|
||||||
"main": "src/nginxconfig/mount.js",
|
"main": "src/nginxconfig/mount.js",
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build:clean && npm run build:template && npm run build:prism && npm run build:static && npm run build:tool",
|
"build": "npm run build:clean && npm run build:template && npm run build:prism && npm run build:static && npm run build:tool",
|
||||||
"build:clean": "do-vue clean",
|
"build:clean": "do-vue clean",
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
"test:eslint": "eslint 'src/**/*.{js,vue}'",
|
"test:eslint": "eslint 'src/**/*.{js,vue}'",
|
||||||
"test:eslint:fix": "npm run test:eslint -- --fix",
|
"test:eslint:fix": "npm run test:eslint -- --fix",
|
||||||
"test:sass-lint": "sass-lint 'src/**/*.scss' --verbose --no-exit --config .sasslintrc",
|
"test:sass-lint": "sass-lint 'src/**/*.scss' --verbose --no-exit --config .sasslintrc",
|
||||||
"test:i18n-packs": "node -r esm src/nginxconfig/i18n/verify.js"
|
"test:i18n-packs": "node --es-module-specifier-resolution=node src/nginxconfig/i18n/verify.js"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"testRegex": "/test/.*.js?$"
|
"testRegex": "/test/.*.js?$"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -24,9 +24,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs').promises;
|
import { promises as fs } from 'fs';
|
||||||
const path = require('path');
|
import { URL } from 'url';
|
||||||
const fetch = require('node-fetch');
|
import fetch from 'node-fetch';
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
const resp = await fetch('https://assets.digitalocean.com/prism/prism.css');
|
const resp = await fetch('https://assets.digitalocean.com/prism/prism.css');
|
||||||
|
@ -35,8 +35,11 @@ const main = async () => {
|
||||||
// Fix $676767 -> #676767
|
// Fix $676767 -> #676767
|
||||||
const fixed = text.replace(/:\s*\$((?:[0-9a-fA-F]{3}){1,2});/g, ':#$1;');
|
const fixed = text.replace(/:\s*\$((?:[0-9a-fA-F]{3}){1,2});/g, ':#$1;');
|
||||||
|
|
||||||
const buildDir = path.join(__dirname, '..', '..', '..', 'build');
|
const buildDir = '../../../build';
|
||||||
await fs.writeFile(path.join(buildDir, 'prism.css'), fixed);
|
await fs.writeFile(new URL(`${buildDir}/prism.css`, import.meta.url), fixed);
|
||||||
};
|
};
|
||||||
|
|
||||||
main().then(() => {});
|
main().then(() => {}).catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
|
@ -24,13 +24,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
import fs from 'fs';
|
||||||
const fs = require('fs');
|
import { URL } from 'url';
|
||||||
|
|
||||||
// Fetch the posthtml template and convert it to an ejs template
|
// Fetch the posthtml template and convert it to an ejs template
|
||||||
const main = () => {
|
const main = () => {
|
||||||
const buildDir = path.join(__dirname, '..', '..', '..', 'build');
|
const buildDir = '../../../build';
|
||||||
let template = fs.readFileSync(path.join(buildDir, 'base.html'), 'utf8');
|
let template = fs.readFileSync(new URL(`${buildDir}/base.html`, import.meta.url), 'utf8');
|
||||||
|
|
||||||
// Inject our title now
|
// Inject our title now
|
||||||
template = template.replace('<block name="title"><title>DigitalOcean</title></block>', '<title>NGINXConfig | DigitalOcean</title>');
|
template = template.replace('<block name="title"><title>DigitalOcean</title></block>', '<title>NGINXConfig | DigitalOcean</title>');
|
||||||
|
@ -38,7 +38,7 @@ const main = () => {
|
||||||
// Inject our app mounting point
|
// Inject our app mounting point
|
||||||
template = template.replace('<block name="content"></block>', '<div id="app"></div>');
|
template = template.replace('<block name="content"></block>', '<div id="app"></div>');
|
||||||
|
|
||||||
fs.writeFileSync(path.join(buildDir, 'index.html'), template);
|
fs.writeFileSync(new URL(`${buildDir}/index.html`, import.meta.url), template);
|
||||||
};
|
};
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const yaml = require('json-to-pretty-yaml');
|
import yaml from 'json-to-pretty-yaml';
|
||||||
|
|
||||||
export default yamlConf => {
|
export default yamlConf => {
|
||||||
return yaml.stringify(yamlConf);
|
return yaml.stringify(yamlConf);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -26,9 +26,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import VueI18n from 'vue-i18n';
|
import VueI18n from 'vue-i18n';
|
||||||
import { defaultPack, defaultPackData } from '../util/language_pack_default';
|
import { defaultPack, defaultPackData, toSep, availablePacks } from '../util/language_packs';
|
||||||
import { toSep } from '../util/language_pack_name';
|
|
||||||
import { languagePackContext, availablePacks } from '../util/language_pack_context';
|
|
||||||
|
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
|
|
||||||
|
@ -37,32 +35,58 @@ const i18nPacks = {};
|
||||||
i18nPacks[defaultPack] = defaultPackData;
|
i18nPacks[defaultPack] = defaultPackData;
|
||||||
const loadedI18nPacks = [defaultPack];
|
const loadedI18nPacks = [defaultPack];
|
||||||
|
|
||||||
// Load in languages data from other packs
|
// Cache the i18n instance
|
||||||
// Use webpack magic to only build chunks for lang/languages.js
|
let i18n = null;
|
||||||
const languagesContext = require.context('.', true, /^\.\/[^/]+\/languages\.js$/, 'sync');
|
|
||||||
for (const availablePack of availablePacks) {
|
|
||||||
if (availablePack === defaultPack) continue;
|
|
||||||
i18nPacks[availablePack] = { languages: languagesContext(`./${toSep(availablePack, '-')}/languages.js`).default };
|
|
||||||
}
|
|
||||||
|
|
||||||
export const i18n = new VueI18n({
|
export const getI18n = async () => {
|
||||||
locale: defaultPack,
|
// Use cached if available
|
||||||
fallbackLocale: defaultPack,
|
if (i18n) return i18n;
|
||||||
messages: i18nPacks,
|
|
||||||
});
|
|
||||||
|
|
||||||
const loadLanguagePack = pack => {
|
// Load in languages data from other packs
|
||||||
|
// Use webpack magic to only build chunks for lang/languages.js
|
||||||
|
// These are eagerly loaded by Webpack, so don't generate extra chunks, and return an already resolved Promise
|
||||||
|
for (const availablePack of availablePacks) {
|
||||||
|
if (availablePack === defaultPack) continue;
|
||||||
|
if (i18nPacks[availablePack]) continue;
|
||||||
|
const { default: languageData } = await import(
|
||||||
|
/* webpackInclude: /i18n\/[^/]+\/languages\.js$/ */
|
||||||
|
/* webpackMode: "eager" */
|
||||||
|
`./${toSep(availablePack, '-')}/languages.js`
|
||||||
|
);
|
||||||
|
i18nPacks[availablePack] = { languages: languageData };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store and return the i18n instance with the loaded packs
|
||||||
|
i18n = new VueI18n({
|
||||||
|
locale: defaultPack,
|
||||||
|
fallbackLocale: defaultPack,
|
||||||
|
messages: i18nPacks,
|
||||||
|
});
|
||||||
|
return i18n;
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadLanguagePack = async pack => {
|
||||||
// If same language, do nothing
|
// If same language, do nothing
|
||||||
if (i18n.locale === pack) return;
|
if (i18n.locale === pack) return;
|
||||||
|
|
||||||
// If language already loaded, do nothing
|
// If language already loaded, do nothing
|
||||||
if (loadedI18nPacks.includes(pack)) return;
|
if (loadedI18nPacks.includes(pack)) return;
|
||||||
|
|
||||||
// Load the pack with webpack magic
|
// Load in the full pack
|
||||||
return languagePackContext(`./${toSep(pack, '-')}/index.js`).then(packData => i18nPacks[pack] = packData.default);
|
// Use webpack magic to only build chunks for lang/index.js
|
||||||
|
const { default: packData } = await import(
|
||||||
|
/* webpackInclude: /i18n\/[^/]+\/index\.js$/ */
|
||||||
|
/* webpackMode: "lazy" */
|
||||||
|
`./${toSep(pack, '-')}/index.js`
|
||||||
|
);
|
||||||
|
i18nPacks[pack] = packData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setLanguagePack = async pack => {
|
export const setLanguagePack = async pack => {
|
||||||
|
// If i18n not loaded, do nothing
|
||||||
|
if (!i18n) return;
|
||||||
|
|
||||||
|
// Load the pack if not already loaded, and set it as active
|
||||||
await loadLanguagePack(pack);
|
await loadLanguagePack(pack);
|
||||||
i18n.locale = pack;
|
i18n.locale = pack;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -26,19 +26,11 @@ THE SOFTWARE.
|
||||||
|
|
||||||
import { readdirSync, readFileSync } from 'fs';
|
import { readdirSync, readFileSync } from 'fs';
|
||||||
import { join, sep } from 'path';
|
import { join, sep } from 'path';
|
||||||
|
import { URL } from 'url';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { defaultPack } from '../util/language_pack_default';
|
import { defaultPack, toSep, fromSep } from '../util/language_packs';
|
||||||
import { toSep, fromSep } from '../util/language_pack_name';
|
|
||||||
import snakeToCamel from '../util/snake_to_camel';
|
import snakeToCamel from '../util/snake_to_camel';
|
||||||
|
|
||||||
// Load all the packs in
|
|
||||||
const packs = {};
|
|
||||||
const packDirectories = readdirSync(__dirname, { withFileTypes: true })
|
|
||||||
.filter(dirent => dirent.isDirectory())
|
|
||||||
.map(dirent => dirent.name);
|
|
||||||
for (const packDirectory of packDirectories)
|
|
||||||
packs[fromSep(packDirectory, '-')] = require(`./${packDirectory}/index.js`).default;
|
|
||||||
|
|
||||||
// Recursively get all keys in a i18n pack object fragment
|
// Recursively get all keys in a i18n pack object fragment
|
||||||
const explore = packFragment => {
|
const explore = packFragment => {
|
||||||
const foundKeys = new Set();
|
const foundKeys = new Set();
|
||||||
|
@ -61,7 +53,7 @@ const explore = packFragment => {
|
||||||
const files = directory => {
|
const files = directory => {
|
||||||
const foundFiles = new Set();
|
const foundFiles = new Set();
|
||||||
|
|
||||||
for (const dirent of readdirSync(join(__dirname, directory), { withFileTypes: true })) {
|
for (const dirent of readdirSync(new URL(`./${directory}`, import.meta.url), { withFileTypes: true })) {
|
||||||
const base = join(directory, dirent.name);
|
const base = join(directory, dirent.name);
|
||||||
|
|
||||||
// If this is a file, store it
|
// If this is a file, store it
|
||||||
|
@ -83,7 +75,7 @@ const files = directory => {
|
||||||
|
|
||||||
// Get all the todo items in a file
|
// Get all the todo items in a file
|
||||||
const todos = file => {
|
const todos = file => {
|
||||||
const content = readFileSync(join(__dirname, file), 'utf8');
|
const content = readFileSync(new URL(`./${file}`, import.meta.url), 'utf8');
|
||||||
const lines = content.split('\n');
|
const lines = content.split('\n');
|
||||||
const items = [];
|
const items = [];
|
||||||
|
|
||||||
|
@ -105,63 +97,78 @@ const fileToObject = file => file
|
||||||
// Replace sep with period and use camelCase
|
// Replace sep with period and use camelCase
|
||||||
.split(sep).map(dir => snakeToCamel(dir)).join('.');
|
.split(sep).map(dir => snakeToCamel(dir)).join('.');
|
||||||
|
|
||||||
// Get all the keys for the default "source" language pack
|
const main = async () => {
|
||||||
const defaultKeys = explore(packs[defaultPack]);
|
// Load all the packs in
|
||||||
|
const packs = {};
|
||||||
|
const packDirectories = readdirSync(new URL('./', import.meta.url), { withFileTypes: true })
|
||||||
|
.filter(dirent => dirent.isDirectory())
|
||||||
|
.map(dirent => dirent.name);
|
||||||
|
for (const packDirectory of packDirectories)
|
||||||
|
packs[fromSep(packDirectory, '-')] = await import(`./${packDirectory}/index.js`).then(pack => pack.default);
|
||||||
|
|
||||||
// Track if we need to exit with an error
|
// Get all the keys for the default "source" language pack
|
||||||
let hadError = false;
|
const defaultKeys = explore(packs[defaultPack]);
|
||||||
|
|
||||||
// Work through all the packs and compare to default
|
// Track if we need to exit with an error
|
||||||
for (const [pack, packData] of Object.entries(packs)) {
|
let hadError = false;
|
||||||
console.log(chalk.underline(`Language pack \`${pack}\``));
|
|
||||||
|
|
||||||
// Get the base data
|
// Work through all the packs and compare to default
|
||||||
const packKeys = explore(packData);
|
for (const [pack, packData] of Object.entries(packs)) {
|
||||||
const packFiles = files(toSep(pack, '-'));
|
console.log(chalk.underline(`Language pack \`${pack}\``));
|
||||||
console.log(` Found ${packKeys.size.toLocaleString()} keys, ${packFiles.size.toLocaleString()} files`);
|
|
||||||
|
|
||||||
// Track all our errors and warnings
|
// Get the base data
|
||||||
const errors = [], warnings = [];
|
const packKeys = explore(packData);
|
||||||
|
const packFiles = files(toSep(pack, '-'));
|
||||||
|
console.log(` Found ${packKeys.size.toLocaleString()} keys, ${packFiles.size.toLocaleString()} files`);
|
||||||
|
|
||||||
// Get all the keys and the set differences
|
// Track all our errors and warnings
|
||||||
const missingKeys = [...defaultKeys].filter(x => !packKeys.has(x));
|
const errors = [], warnings = [];
|
||||||
const extraKeys = [...packKeys].filter(x => !defaultKeys.has(x));
|
|
||||||
|
|
||||||
// Missing keys and extra keys are errors
|
// Get all the keys and the set differences
|
||||||
missingKeys.forEach(key => errors.push(`Missing key \`${key}\``));
|
const missingKeys = [...defaultKeys].filter(x => !packKeys.has(x));
|
||||||
extraKeys.forEach(key => errors.push(`Unexpected key \`${key}\``));
|
const extraKeys = [...packKeys].filter(x => !defaultKeys.has(x));
|
||||||
|
|
||||||
// Get all the files in the pack directory
|
// Missing keys and extra keys are errors
|
||||||
const packKeyFiles = new Set([...packFiles].filter(file => file.split(sep).slice(-1)[0] !== 'index.js'));
|
missingKeys.forEach(key => errors.push(`Missing key \`${key}\``));
|
||||||
|
extraKeys.forEach(key => errors.push(`Unexpected key \`${key}\``));
|
||||||
|
|
||||||
// Get the objects from the pack keys
|
// Get all the files in the pack directory
|
||||||
const packKeyObjects = new Set([...packKeys]
|
const packKeyFiles = new Set([...packFiles].filter(file => file.split(sep).slice(-1)[0] !== 'index.js'));
|
||||||
.map(key => key.split('.').slice(0, -1).join('.')));
|
|
||||||
|
|
||||||
// Warn for any files that aren't used as pack objects
|
// Get the objects from the pack keys
|
||||||
[...packKeyFiles].filter(file => !packKeyObjects.has(fileToObject(file)))
|
const packKeyObjects = new Set([...packKeys]
|
||||||
.forEach(file => warnings.push(`Unused file \`${file}\``));
|
.map(key => key.split('.').slice(0, -1).join('.')));
|
||||||
|
|
||||||
// Locate any todos in each file as a warning
|
// Warn for any files that aren't used as pack objects
|
||||||
for (const file of packFiles)
|
[...packKeyFiles].filter(file => !packKeyObjects.has(fileToObject(file)))
|
||||||
todos(file).forEach(todo => warnings.push(`TODO in \`${file}\` on line ${todo[0]}`));
|
.forEach(file => warnings.push(`Unused file \`${file}\``));
|
||||||
|
|
||||||
// Output the pack results
|
// Locate any todos in each file as a warning
|
||||||
if (warnings.length)
|
for (const file of packFiles)
|
||||||
for (const warning of warnings)
|
todos(file).forEach(todo => warnings.push(`TODO in \`${file}\` on line ${todo[0]}`));
|
||||||
console.log(` ${chalk.yellow('warning')} ${warning}`);
|
|
||||||
if (errors.length)
|
|
||||||
for (const error of errors)
|
|
||||||
console.log(` ${chalk.red('error')} ${error}`);
|
|
||||||
if (!errors.length && !warnings.length)
|
|
||||||
console.log(` ${chalk.green('No issues')}`);
|
|
||||||
|
|
||||||
// If we had errors, script should exit 1
|
// Output the pack results
|
||||||
if (errors.length) hadError = true;
|
if (warnings.length)
|
||||||
|
for (const warning of warnings)
|
||||||
|
console.log(` ${chalk.yellow('warning')} ${warning}`);
|
||||||
|
if (errors.length)
|
||||||
|
for (const error of errors)
|
||||||
|
console.log(` ${chalk.red('error')} ${error}`);
|
||||||
|
if (!errors.length && !warnings.length)
|
||||||
|
console.log(` ${chalk.green('No issues')}`);
|
||||||
|
|
||||||
// Linebreak before next pack or exit
|
// If we had errors, script should exit 1
|
||||||
console.log(chalk.reset());
|
if (errors.length) hadError = true;
|
||||||
}
|
|
||||||
|
|
||||||
// Exit 1 if we had errors
|
// Linebreak before next pack or exit
|
||||||
if (hadError) process.exit(1);
|
console.log(chalk.reset());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit 1 if we had errors
|
||||||
|
if (hadError) process.exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
main().then(() => {}).catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -28,11 +28,14 @@ THE SOFTWARE.
|
||||||
import './scss/style.scss';
|
import './scss/style.scss';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import './util/prism_bundle';
|
import './util/prism_bundle';
|
||||||
import { i18n } from './i18n/setup';
|
import { getI18n } from './i18n/setup';
|
||||||
import App from './templates/app';
|
import App from './templates/app';
|
||||||
|
|
||||||
// Run the app
|
// Load the i18n languages and run the app
|
||||||
new Vue({
|
getI18n().then(i18n => {
|
||||||
i18n,
|
new Vue({
|
||||||
render: h => h(App),
|
i18n,
|
||||||
}).$mount('#app');
|
render: h => h(App),
|
||||||
|
}).$mount('#app');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -133,8 +133,7 @@ THE SOFTWARE.
|
||||||
import isObject from '../util/is_object';
|
import isObject from '../util/is_object';
|
||||||
import analytics from '../util/analytics';
|
import analytics from '../util/analytics';
|
||||||
import browserLanguage from '../util/browser_language';
|
import browserLanguage from '../util/browser_language';
|
||||||
import { defaultPack } from '../util/language_pack_default';
|
import { defaultPack, availablePacks } from '../util/language_packs';
|
||||||
import { availablePacks } from '../util/language_pack_context';
|
|
||||||
|
|
||||||
import { setLanguagePack } from '../i18n/setup';
|
import { setLanguagePack } from '../i18n/setup';
|
||||||
import generators from '../generators';
|
import generators from '../generators';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fromSep } from './language_pack_name';
|
import { fromSep } from './language_packs';
|
||||||
|
|
||||||
export default availablePacks => {
|
export default availablePacks => {
|
||||||
if (typeof window === 'object' && typeof window.navigator === 'object') {
|
if (typeof window === 'object' && typeof window.navigator === 'object') {
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020 DigitalOcean
|
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE or https://mit-license.org/
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions :
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { fromSep } from './language_pack_name';
|
|
||||||
|
|
||||||
// Use webpack magic to only build chunks for lang/index.js, not subdirectories (e.g. lang/templates/index.js)
|
|
||||||
export const languagePackContext = require.context('../i18n', true, /^\.\/[^/]+\/index\.js$/, 'lazy');
|
|
||||||
|
|
||||||
// Webpack magic to get all the packs that are available
|
|
||||||
export const availablePacks = Object.freeze(languagePackContext
|
|
||||||
.keys()
|
|
||||||
.map(pack => pack.match(/^\.\/([^/]+)\/index\.js$/))
|
|
||||||
.filter(pack => pack !== null)
|
|
||||||
.map(pack => fromSep(pack[1], '-')));
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020 DigitalOcean
|
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE or https://mit-license.org/
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions :
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
export const defaultPack = 'en';
|
|
||||||
|
|
||||||
export { default as defaultPackData } from '../i18n/en';
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -24,6 +24,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export const defaultPack = 'en';
|
||||||
|
|
||||||
|
export { default as defaultPackData } from '../i18n/en';
|
||||||
|
|
||||||
export const toSep = (pack, sep) => pack
|
export const toSep = (pack, sep) => pack
|
||||||
.match(/^([a-z]+)([A-Z]*)$/)
|
.match(/^([a-z]+)([A-Z]*)$/)
|
||||||
.slice(1)
|
.slice(1)
|
||||||
|
@ -32,3 +36,13 @@ export const toSep = (pack, sep) => pack
|
||||||
.join(sep);
|
.join(sep);
|
||||||
|
|
||||||
export const fromSep = (pack, sep) => pack.split(sep, 2)[0].toLowerCase() + (pack.split(sep, 2)[1] || '').toUpperCase();
|
export const fromSep = (pack, sep) => pack.split(sep, 2)[0].toLowerCase() + (pack.split(sep, 2)[1] || '').toUpperCase();
|
||||||
|
|
||||||
|
// Use webpack magic to get all the language packs we've bundled
|
||||||
|
// If not in a webpack context, return no packs
|
||||||
|
/* global __webpack_modules__ */
|
||||||
|
export const availablePacks = typeof __webpack_modules__ === 'undefined'
|
||||||
|
? []
|
||||||
|
: Object.keys(__webpack_modules__)
|
||||||
|
.map(pack => pack.match(/i18n\/([^/]+)\/languages\.js$/))
|
||||||
|
.filter(pack => pack !== null)
|
||||||
|
.map(pack => fromSep(pack[1], '-'));
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2021 DigitalOcean
|
Copyright 2022 DigitalOcean
|
||||||
|
|
||||||
This code is licensed under the MIT License.
|
This code is licensed under the MIT License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
@ -24,12 +24,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||||
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
import DuplicatePackageCheckerPlugin from 'duplicate-package-checker-webpack-plugin';
|
||||||
const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin');
|
import WebpackRequireFrom from 'webpack-require-from';
|
||||||
const WebpackRequireFrom = require('webpack-require-from');
|
import { URL, fileURLToPath } from 'url';
|
||||||
|
|
||||||
module.exports = {
|
export default {
|
||||||
publicPath: './',
|
publicPath: './',
|
||||||
outputDir: 'dist',
|
outputDir: 'dist',
|
||||||
filenameHashing: false, // Don't hash the output, so we can embed on the DigitalOcean Community
|
filenameHashing: false, // Don't hash the output, so we can embed on the DigitalOcean Community
|
||||||
|
@ -43,10 +43,10 @@ module.exports = {
|
||||||
// Fix dynamic imports from CDN (inject as first entry point before any imports can happen)
|
// Fix dynamic imports from CDN (inject as first entry point before any imports can happen)
|
||||||
{ apply: compiler => {
|
{ apply: compiler => {
|
||||||
compiler.options.entry.app.import.unshift(
|
compiler.options.entry.app.import.unshift(
|
||||||
path.join(__dirname, 'src', 'nginxconfig', 'build', 'webpack-dynamic-import.js'),
|
fileURLToPath(new URL('src/nginxconfig/build/webpack-dynamic-import.js', import.meta.url)),
|
||||||
);
|
);
|
||||||
} },
|
} },
|
||||||
new WebpackRequireFrom({ methodName: '__webpackDynamicImportURL' }),
|
new WebpackRequireFrom({ methodName: '__webpackDynamicImportURL', suppressErrors: true }),
|
||||||
// Analyze the bundle
|
// Analyze the bundle
|
||||||
new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false }),
|
new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false }),
|
||||||
new DuplicatePackageCheckerPlugin(),
|
new DuplicatePackageCheckerPlugin(),
|
||||||
|
@ -68,7 +68,7 @@ module.exports = {
|
||||||
|
|
||||||
// Use a custom HTML template
|
// Use a custom HTML template
|
||||||
config.plugin('html').tap(options => {
|
config.plugin('html').tap(options => {
|
||||||
options[0].template = path.join(__dirname, 'build', 'index.html');
|
options[0].template = fileURLToPath(new URL('build/index.html', import.meta.url));
|
||||||
return options;
|
return options;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue