UNPKG

2.58 kBJavaScriptView Raw
1/**
2 * Copyright (c) 2015-present, Facebook, Inc.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8'use strict';
9
10const chalk = require('chalk');
11const path = require('path');
12
13class 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 // Unknown issuer, probably webpack internals
23 if (!request.context.issuer) {
24 return callback();
25 }
26 if (
27 // If this resolves to a node_module, we don't care what happens next
28 request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
29 request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 ||
30 // Make sure this request was manual
31 !request.__innerRequest_request
32 ) {
33 return callback();
34 }
35 // Resolve the issuer from our appSrc and make sure it's one of our files
36 // Maybe an indexOf === 0 would be better?
37 const relative = path.relative(appSrc, request.context.issuer);
38 // If it's not in src/ or a subdirectory, not our request!
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 // Find path from src to the requested file
50 // Error if in a parent directory of src/
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
81module.exports = ModuleScopePlugin;