UNPKG

6.92 kBJavaScriptView Raw
1"use strict";
2/* -----------------------------------------------------------------------------
3| Copyright (c) Jupyter Development Team.
4| Distributed under the terms of the Modified BSD License.
5|----------------------------------------------------------------------------*/
6var __importStar = (this && this.__importStar) || function (mod) {
7 if (mod && mod.__esModule) return mod;
8 var result = {};
9 if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
10 result["default"] = mod;
11 return result;
12};
13Object.defineProperty(exports, "__esModule", { value: true });
14const MiniCssExtractPlugin = require("mini-css-extract-plugin");
15const fs = __importStar(require("fs-extra"));
16const glob = __importStar(require("glob"));
17const path = __importStar(require("path"));
18const utils = __importStar(require("./utils"));
19/**
20 * A namespace for JupyterLab build utilities.
21 */
22var Build;
23(function (Build) {
24 /**
25 * Ensures that the assets of plugin packages are populated for a build.
26 *
27 * @ Returns An array of lab extension config data.
28 */
29 function ensureAssets(options) {
30 const { output, packageNames } = options;
31 const themeConfig = [];
32 // Get the CSS imports.
33 // We must import the application CSS first.
34 // The order of the rest does not matter.
35 // We explicitly ignore themes so they can be loaded dynamically.
36 let cssImports = [];
37 let appCSS = '';
38 packageNames.forEach(name => {
39 const packageDataPath = require.resolve(path.join(name, 'package.json'));
40 const packageDir = path.dirname(packageDataPath);
41 const data = utils.readJSONFile(packageDataPath);
42 const extension = normalizeExtension(data);
43 const { schemaDir, themePath } = extension;
44 // Handle styles.
45 if (data.style) {
46 if (data.name === '@jupyterlab/application-extension') {
47 appCSS = name + '/' + data.style;
48 }
49 else if (!data.jupyterlab.themePath) {
50 cssImports.push(name + '/' + data.style);
51 }
52 }
53 // Handle schemas.
54 if (schemaDir) {
55 const schemas = glob.sync(path.join(path.join(packageDir, schemaDir), '*'));
56 const destination = path.join(output, 'schemas', name);
57 // Remove the existing directory if necessary.
58 if (fs.existsSync(destination)) {
59 try {
60 const oldPackagePath = path.join(destination, 'package.json.orig');
61 const oldPackageData = utils.readJSONFile(oldPackagePath);
62 if (oldPackageData.version === data.version) {
63 fs.removeSync(destination);
64 }
65 }
66 catch (e) {
67 fs.removeSync(destination);
68 }
69 }
70 // Make sure the schema directory exists.
71 fs.mkdirpSync(destination);
72 // Copy schemas.
73 schemas.forEach(schema => {
74 const file = path.basename(schema);
75 fs.copySync(schema, path.join(destination, file));
76 });
77 // Write the package.json file for future comparison.
78 fs.copySync(path.join(packageDir, 'package.json'), path.join(destination, 'package.json.orig'));
79 }
80 if (!themePath) {
81 return;
82 }
83 themeConfig.push({
84 mode: 'production',
85 entry: {
86 index: path.join(name, themePath)
87 },
88 output: {
89 path: path.resolve(path.join(output, 'themes', name)),
90 // we won't use these JS files, only the extracted CSS
91 filename: '[name].js'
92 },
93 module: {
94 rules: [
95 {
96 test: /\.css$/,
97 use: [MiniCssExtractPlugin.loader, 'css-loader']
98 },
99 {
100 test: /\.svg/,
101 use: [{ loader: 'svg-url-loader', options: { encoding: 'none' } }]
102 },
103 {
104 test: /\.(png|jpg|gif|ttf|woff|woff2|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
105 use: [{ loader: 'url-loader', options: { limit: 10000 } }]
106 }
107 ]
108 },
109 plugins: [
110 new MiniCssExtractPlugin({
111 // Options similar to the same options in webpackOptions.output
112 // both options are optional
113 filename: '[name].css',
114 chunkFilename: '[id].css'
115 })
116 ]
117 });
118 });
119 // Template the CSS index file.
120 cssImports = cssImports.sort((a, b) => a.localeCompare(b));
121 let cssContents = '/* This is a generated file of CSS imports */';
122 cssContents +=
123 '\n/* It was generated by @jupyterlab/buildutils in Build.ensureAssets() */';
124 cssContents += `\n@import url('~${appCSS}');`;
125 cssImports.forEach(cssImport => {
126 cssContents += `\n@import url('~${cssImport}');`;
127 });
128 cssContents += '\n';
129 const indexCSSPath = path.join(output, 'imports.css');
130 // Make sure the output dir exists before writing to it.
131 if (!fs.existsSync(output)) {
132 fs.mkdirSync(output);
133 }
134 fs.writeFileSync(indexCSSPath, cssContents, { encoding: 'utf8' });
135 return themeConfig;
136 }
137 Build.ensureAssets = ensureAssets;
138 /**
139 * Returns JupyterLab extension metadata from a module.
140 */
141 function normalizeExtension(module) {
142 let { jupyterlab, main, name } = module;
143 main = main || 'index.js';
144 if (!jupyterlab) {
145 throw new Error(`Module ${name} does not contain JupyterLab metadata.`);
146 }
147 let { extension, mimeExtension, schemaDir, themePath } = jupyterlab;
148 extension = extension === true ? main : extension;
149 mimeExtension = mimeExtension === true ? main : mimeExtension;
150 if (extension && mimeExtension && extension === mimeExtension) {
151 const message = 'extension and mimeExtension cannot be the same export.';
152 throw new Error(message);
153 }
154 return { extension, mimeExtension, schemaDir, themePath };
155 }
156 Build.normalizeExtension = normalizeExtension;
157})(Build = exports.Build || (exports.Build = {}));
158//# sourceMappingURL=build.js.map
\No newline at end of file