1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | 'use strict';
|
9 |
|
10 | const chalk = require('chalk');
|
11 | const path = require('path');
|
12 |
|
13 | class ModuleScopePlugin {
|
14 | constructor(appSrc, allowedFiles = []) {
|
15 | this.appSrc = appSrc;
|
16 | this.allowedFiles = new Set(allowedFiles);
|
17 | }
|
18 |
|
19 | apply(resolver) {
|
20 | const { appSrc } = this;
|
21 | resolver.plugin('file', (request, callback) => {
|
22 |
|
23 | if (!request.context.issuer) {
|
24 | return callback();
|
25 | }
|
26 | if (
|
27 |
|
28 | request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
|
29 | request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 ||
|
30 |
|
31 | !request.__innerRequest_request
|
32 | ) {
|
33 | return callback();
|
34 | }
|
35 |
|
36 |
|
37 | const relative = path.relative(appSrc, request.context.issuer);
|
38 |
|
39 | if (relative.startsWith('../') || relative.startsWith('..\\')) {
|
40 | return callback();
|
41 | }
|
42 | const requestFullPath = path.resolve(
|
43 | path.dirname(request.context.issuer),
|
44 | request.__innerRequest_request
|
45 | );
|
46 | if (this.allowedFiles.has(requestFullPath)) {
|
47 | return callback();
|
48 | }
|
49 |
|
50 |
|
51 | const requestRelative = path.relative(appSrc, requestFullPath);
|
52 | if (
|
53 | requestRelative.startsWith('../') ||
|
54 | requestRelative.startsWith('..\\')
|
55 | ) {
|
56 | callback(
|
57 | new Error(
|
58 | `You attempted to import ${chalk.cyan(
|
59 | request.__innerRequest_request
|
60 | )} which falls outside of the project ${chalk.cyan(
|
61 | 'src/'
|
62 | )} directory. ` +
|
63 | `Relative imports outside of ${chalk.cyan(
|
64 | 'src/'
|
65 | )} are not supported. ` +
|
66 | `You can either move it inside ${chalk.cyan(
|
67 | 'src/'
|
68 | )}, or add a symlink to it from project's ${chalk.cyan(
|
69 | 'node_modules/'
|
70 | )}.`
|
71 | ),
|
72 | request
|
73 | );
|
74 | } else {
|
75 | callback();
|
76 | }
|
77 | });
|
78 | }
|
79 | }
|
80 |
|
81 | module.exports = ModuleScopePlugin;
|