This repository has been archived by the owner on Sep 1, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
builder.ts
170 lines (148 loc) · 4.27 KB
/
builder.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
import * as ExtractTextPlugin
from 'extract-text-webpack-plugin';
import * as path
from 'path';
import * as webpack
from 'webpack';
import {
Config
} from 'webpack-config';
import {
JupyterLabPlugin
} from './plugin';
/**
* The default file loaders.
*/
const
DEFAULT_LOADERS = [
{ test: /\.json$/, loader: 'json-loader' },
{ test: /\.html$/, loader: 'file-loader' },
{ test: /\.(jpg|png|gif)$/, loader: 'file-loader' },
{ test: /\.js.map$/, loader: 'file-loader' },
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml' }
];
/**
* Build a JupyterLab extension.
*
* @param options - The options used to build the extension.
*/
export
function buildExtension(options: IBuildOptions) {
let name = options.name;
if (!name) {
throw Error('Must specify a name for the extension');
}
if (!options.entry) {
throw Error('Must specify an entry module');
}
if (!options.outputDir) {
throw Error('Must specify an output directory');
}
// Create the named entry point to the entryPath.
let entry: { [key: string]: string } = {};
entry[name] = options.entry;
let config = new Config().merge({
// The default options.
entry: entry,
output: {
path: path.resolve(options.outputDir),
filename: '[name].bundle.js',
publicPath: `labextension/${name}`
},
node: {
fs: 'empty'
},
debug: true,
bail: true,
plugins: [new JupyterLabPlugin()]
// Add the override options.
}).merge(options.config || {});
// Add the CSS extractors unless explicitly told otherwise.
if (options.extractCSS !== false) {
// Note that we have to use an explicit local public path
// otherwise the urls in the extracted CSS will point to the wrong
// location.
// See https://github.com/webpack/extract-text-webpack-plugin/issues/27#issuecomment-77531770
let loader = ExtractTextPlugin.extract('style-loader', 'css-loader',
{ publicPath: './' });
config.merge({
module: {
loaders: [{ test: /\.css$/, loader: loader }]
},
plugins: [new ExtractTextPlugin('[name].css')]
});
}
// Add the rest of the default loaders unless explicitly told otherwise.
if (options.useDefaultLoaders !== false) {
config.merge({
module: {
loaders: DEFAULT_LOADERS
}
});
}
// Set up and run the WebPack compilation.
let compiler = webpack(config);
compiler.context = name;
compiler.run((err, stats) => {
if (err) {
console.error(err.stack || err);
if ((err as any).details) {
console.error((err as any).details);
}
} else {
console.log(`\n\nSuccessfully built "${name}":\n`);
process.stdout.write(stats.toString({
chunks: true,
modules: false,
chunkModules: false,
colors: require('supports-color')
}) + '\n');
}
});
}
/**
* The options used to build a JupyterLab extension.
*/
export
interface IBuildOptions {
/**
* The name of the extension.
*/
name: string;
/**
* The module to load as the entry point.
*
* The module should export a plugin configuration or array of
* plugin configurations.
*/
entry: string;
/**
* The directory in which to put the generated bundle files.
*
* Relative directories are resolved relative to the current
* working directory of the process.
*/
outputDir: string;
/**
* Whether to extract CSS from the bundles (default is True).
*
* Note: no other CSS loaders should be used if not set to False.
*/
extractCSS?: boolean;
/**
* Whether to use the default loaders for some common file types.
*
* See [[DEFAULT_LOADERS]]. The default is True.
*/
useDefaultLoaders?: boolean;
/**
* Extra webpack configuration.
*/
config?: webpack.Configuration;
}