mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-04-30 18:32:33 +08:00
Add module scope plugin (#2189)
* Add module scope plugin * Oops * Add comments * Check windows seps too * More descriptive error * Document it
This commit is contained in:
68
packages/react-dev-utils/ModuleScopePlugin.js
vendored
Normal file
68
packages/react-dev-utils/ModuleScopePlugin.js
vendored
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const chalk = require('chalk');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
class ModuleScopePlugin {
|
||||||
|
constructor(appSrc) {
|
||||||
|
this.appSrc = appSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(resolver) {
|
||||||
|
const { appSrc } = this;
|
||||||
|
resolver.plugin('file', (request, callback) => {
|
||||||
|
// Unknown issuer, probably webpack internals
|
||||||
|
if (!request.context.issuer) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
// If this resolves to a node_module, we don't care what happens next
|
||||||
|
request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
|
||||||
|
request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 ||
|
||||||
|
// Make sure this request was manual
|
||||||
|
!request.__innerRequest_request
|
||||||
|
) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
// Resolve the issuer from our appSrc and make sure it's one of our files
|
||||||
|
// Maybe an indexOf === 0 would be better?
|
||||||
|
const relative = path.relative(appSrc, request.context.issuer);
|
||||||
|
// If it's not in src/ or a subdirectory, not our request!
|
||||||
|
if (relative[0] === '.') {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
// Find path from src to the requested file
|
||||||
|
const requestRelative = path.relative(
|
||||||
|
appSrc,
|
||||||
|
path.resolve(
|
||||||
|
path.dirname(request.context.issuer),
|
||||||
|
request.__innerRequest_request
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// Error if in a parent directory of src/
|
||||||
|
if (requestRelative[0] === '.') {
|
||||||
|
callback(
|
||||||
|
new Error(
|
||||||
|
`You attempted to import ${chalk.cyan(request.__innerRequest_request)} which falls outside of the project ${chalk.cyan('src/')} directory. ` +
|
||||||
|
`Relative imports outside of ${chalk.cyan('src/')} are not supported. ` +
|
||||||
|
`You can either move it inside ${chalk.cyan('src/')}, or add a symlink to it from project's ${chalk.cyan('node_modules/')}.`
|
||||||
|
),
|
||||||
|
request
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ModuleScopePlugin;
|
||||||
@@ -56,6 +56,26 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### `new ModuleScopePlugin(appSrc: string)`
|
||||||
|
|
||||||
|
This Webpack plugin ensures that relative imports from app's source directory don't reach outside of it.
|
||||||
|
|
||||||
|
```js
|
||||||
|
var path = require('path');
|
||||||
|
var ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
// ...
|
||||||
|
plugins: [
|
||||||
|
new ModuleScopePlugin(paths.appSrc),
|
||||||
|
// ...
|
||||||
|
],
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### `new WatchMissingNodeModulesPlugin(nodeModulesPath: string)`
|
#### `new WatchMissingNodeModulesPlugin(nodeModulesPath: string)`
|
||||||
|
|
||||||
This Webpack plugin ensures `npm install <library>` forces a project rebuild.<br>
|
This Webpack plugin ensures `npm install <library>` forces a project rebuild.<br>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"getProcessForPort.js",
|
"getProcessForPort.js",
|
||||||
"InterpolateHtmlPlugin.js",
|
"InterpolateHtmlPlugin.js",
|
||||||
"launchEditor.js",
|
"launchEditor.js",
|
||||||
|
"ModuleScopePlugin.js",
|
||||||
"openBrowser.js",
|
"openBrowser.js",
|
||||||
"openChrome.applescript",
|
"openChrome.applescript",
|
||||||
"prepareProxy.js",
|
"prepareProxy.js",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
|
|||||||
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
||||||
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
|
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
|
||||||
const eslintFormatter = require('react-dev-utils/eslintFormatter');
|
const eslintFormatter = require('react-dev-utils/eslintFormatter');
|
||||||
|
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||||
const getClientEnvironment = require('./env');
|
const getClientEnvironment = require('./env');
|
||||||
const paths = require('./paths');
|
const paths = require('./paths');
|
||||||
|
|
||||||
@@ -106,6 +107,14 @@ module.exports = {
|
|||||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||||
'react-native': 'react-native-web',
|
'react-native': 'react-native-web',
|
||||||
},
|
},
|
||||||
|
plugins: [
|
||||||
|
// Prevents users from importing files from outside of src/ (or node_modules/).
|
||||||
|
// This often causes confusion because we only process files within src/ with babel.
|
||||||
|
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
|
||||||
|
// please link the files into your node_modules/ and let module-resolution kick in.
|
||||||
|
// Make sure your source files are compiled, as they will not be processed in any way.
|
||||||
|
new ModuleScopePlugin(paths.appSrc),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
strictExportPresence: true,
|
strictExportPresence: true,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
|||||||
const ManifestPlugin = require('webpack-manifest-plugin');
|
const ManifestPlugin = require('webpack-manifest-plugin');
|
||||||
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
||||||
const eslintFormatter = require('react-dev-utils/eslintFormatter');
|
const eslintFormatter = require('react-dev-utils/eslintFormatter');
|
||||||
|
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||||
const paths = require('./paths');
|
const paths = require('./paths');
|
||||||
const getClientEnvironment = require('./env');
|
const getClientEnvironment = require('./env');
|
||||||
|
|
||||||
@@ -103,6 +104,14 @@ module.exports = {
|
|||||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||||
'react-native': 'react-native-web',
|
'react-native': 'react-native-web',
|
||||||
},
|
},
|
||||||
|
plugins: [
|
||||||
|
// Prevents users from importing files from outside of src/ (or node_modules/).
|
||||||
|
// This often causes confusion because we only process files within src/ with babel.
|
||||||
|
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
|
||||||
|
// please link the files into your node_modules/ and let module-resolution kick in.
|
||||||
|
// Make sure your source files are compiled, as they will not be processed in any way.
|
||||||
|
new ModuleScopePlugin(paths.appSrc),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
strictExportPresence: true,
|
strictExportPresence: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user