Skip to content

Sync #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 18, 2017
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ matrix:
include:
- node_js: 0.10
env: TEST_SUITE=simple
- node_js: 6
env: USE_YARN=yes TEST_SUITE=simple
# There's a weird Yarn/Lerna bug related to prerelease versions.
# TODO: reenable after we ship 1.0.
# - node_js: 6
# env: USE_YARN=yes TEST_SUITE=simple
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ It correctly bundles React in production mode and optimizes the build for the be

The build is minified and the filenames include the hashes.<br>
Your app is ready to be deployed!
<!--TODO: uncoment and maybe revise
A [service worker](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) using an [offline-first caching strategy](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network) is automatically generated.<br>
Your ([progressive web](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app)) app is ready to be deployed!-->

## User Guide

Expand Down Expand Up @@ -162,6 +165,9 @@ Please refer to the [User Guide](https://github.com/facebookincubator/create-rea
* Import CSS and image files directly from JavaScript.
* Autoprefixed CSS, so you don’t need `-webkit` or other prefixes.
* A `build` script to bundle JS, CSS, and images for production, with sourcemaps.
<!--TODO: uncomment
* An offline-first [service worker](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) and a [web app manifest](https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/), meeting all the [Progressive Web App](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app) criteria.
-->

**The feature set is intentionally limited**. It doesn’t support advanced features such as server rendering or CSS modules. The tool is also **non-configurable** because it is hard to provide a cohesive experience and easy updates across a set of tools when the user can tweak anything.

Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-config-react-app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ module.exports = {
],

// https://github.com/benmosher/eslint-plugin-import/tree/master/docs/rules
'import/first': 'error',
'import/no-amd': 'error',
'import/no-webpack-loader-syntax': 'error',

// https://github.com/yannickcr/eslint-plugin-react/tree/master/docs/rules
Expand Down
68 changes: 68 additions & 0 deletions packages/react-dev-utils/ModuleScopePlugin.js
Original file line number Diff line number Diff line change
@@ -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;
41 changes: 39 additions & 2 deletions packages/react-dev-utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ var publicUrl = '/my-custom-url';
module.exports = {
output: {
// ...
publicPath: publicUrl + '/'
publicPath: publicUrl + '/'
},
// ...
plugins: [
Expand All @@ -56,6 +56,30 @@ 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 = {
// ...
resolve: {
// ...
plugins: [
new ModuleScopePlugin(paths.appSrc),
// ...
],
// ...
},
// ...
}
```

#### `new WatchMissingNodeModulesPlugin(nodeModulesPath: string)`

This Webpack plugin ensures `npm install <library>` forces a project rebuild.<br>
Expand Down Expand Up @@ -112,7 +136,7 @@ console.log('Just cleared the screen!');

#### `eslintFormatter(results: Object): string`

This is our custom ESLint formatter that integrates well with Create React App console output.
This is our custom ESLint formatter that integrates well with Create React App console output.<br>
You can use the default one instead if you prefer so.

```js
Expand Down Expand Up @@ -228,6 +252,19 @@ if (openBrowser('http://localhost:3000')) {
}
```

#### `printHostingInstructions(appPackage: Object, publicUrl: string, publicPath: string, buildFolder: string, useYarn: boolean): void`

Prints hosting instructions after the project is built.

Pass your parsed `package.json` object as `appPackage`, your the URL where you plan to host the app as `publicUrl`, `output.publicPath` from your Webpack configuration as `publicPath`, the `buildFolder` name, and whether to `useYarn` in instructions.

```js
const appPackage = require(paths.appPackageJson);
const publicUrl = paths.publicUrl;
const publicPath = config.output.publicPath;
printHostingInstructions(appPackage, publicUrl, publicPath, 'build', true);
```

#### `webpackHotDevClient.js`

This is an alternative client for [WebpackDevServer](https://github.com/webpack/webpack-dev-server) that shows a syntax error overlay.
Expand Down
10 changes: 5 additions & 5 deletions packages/react-dev-utils/ansiHTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ var Anser = require('anser');
// var base00 = 'ffffff'; // Default Background
var base01 = 'f5f5f5'; // Lighter Background (Used for status bars)
// var base02 = 'c8c8fa'; // Selection Background
var base03 = '969896'; // Comments, Invisibles, Line Highlighting
var base03 = '6e6e6e'; // Comments, Invisibles, Line Highlighting
// var base04 = 'e8e8e8'; // Dark Foreground (Used for status bars)
var base05 = '333333'; // Default Foreground, Caret, Delimiters, Operators
// var base06 = 'ffffff'; // Light Foreground (Not often used)
// var base07 = 'ffffff'; // Light Background (Not often used)
var base08 = 'ed6a43'; // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
var base08 = '881280'; // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
// var base09 = '0086b3'; // Integers, Boolean, Constants, XML Attributes, Markup Link Url
// var base0A = '795da3'; // Classes, Markup Bold, Search Text Background
var base0B = '183691'; // Strings, Inherited Class, Markup Code, Diff Inserted
var base0C = '183691'; // Support, Regular Expressions, Escape Characters, Markup Quotes
var base0B = '1155cc'; // Strings, Inherited Class, Markup Code, Diff Inserted
var base0C = '994500'; // Support, Regular Expressions, Escape Characters, Markup Quotes
// var base0D = '795da3'; // Functions, Methods, Attribute IDs, Headings
var base0E = 'a71d5d'; // Keywords, Storage, Selector, Markup Italic, Diff Changed
var base0E = 'c80000'; // Keywords, Storage, Selector, Markup Italic, Diff Changed
// var base0F = '333333'; // Deprecated, Opening/Closing Embedded Language Tags e.g. <?php ?>

// Map ANSI colors from what babel-code-frame uses to base16-github
Expand Down
19 changes: 18 additions & 1 deletion packages/react-dev-utils/eslintFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,23 @@ function isError(message) {

function formatter(results) {
let output = '\n';
let hasErrors = false;
let reportContainsErrorRuleIDs = false;

results.forEach(result => {
let messages = result.messages;
if (messages.length === 0) {
return;
}

let hasErrors = false;
messages = messages.map(message => {
let messageType;
if (isError(message)) {
messageType = 'error';
hasErrors = true;
if (message.ruleId) {
reportContainsErrorRuleIDs = true;
}
} else {
messageType = 'warn';
}
Expand Down Expand Up @@ -61,6 +65,19 @@ function formatter(results) {
output += `${outputTable}\n\n`;
});

if (reportContainsErrorRuleIDs) {
// Unlike with warnings, we have to do it here.
// We have similar code in react-scripts for warnings,
// but warnings can appear in multiple files so we only
// print it once at the end. For errors, however, we print
// it here because we always show at most one error, and
// we can only be sure it's an ESLint error before exiting
// this function.
output += 'Search for the ' +
chalk.underline(chalk.red('rule keywords')) +
' to learn more about each error.';
}

return output;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/react-dev-utils/formatWebpackMessages.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ function formatMessage(message, isError) {
lines[1]
.replace("Cannot resolve 'file' or 'directory' ", '')
.replace('Cannot resolve module ', '')
.replace('Error: ', ''),
.replace('Error: ', '')
.replace('[CaseSensitivePathsPlugin] ', ''),
];
}

Expand Down
2 changes: 2 additions & 0 deletions packages/react-dev-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
"getProcessForPort.js",
"InterpolateHtmlPlugin.js",
"launchEditor.js",
"ModuleScopePlugin.js",
"openBrowser.js",
"openChrome.applescript",
"prepareProxy.js",
"printHostingInstructions.js",
"WatchMissingNodeModulesPlugin.js",
"webpackHotDevClient.js"
],
Expand Down
114 changes: 114 additions & 0 deletions packages/react-dev-utils/printHostingInstructions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* 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 url = require('url');

function printHostingInstructions(
appPackage,
publicUrl,
publicPath,
buildFolder,
useYarn
) {
const publicPathname = url.parse(publicPath).pathname;
if (publicUrl && publicUrl.indexOf('.github.io/') !== -1) {
// "homepage": "http://user.github.io/project"
console.log(
`The project was built assuming it is hosted at ${chalk.green(publicPathname)}.`
);
console.log(
`You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.`
);
console.log();
console.log(`The ${chalk.cyan('build')} folder is ready to be deployed.`);
console.log(`To publish it at ${chalk.green(publicUrl)}, run:`);
// If script deploy has been added to package.json, skip the instructions
if (typeof appPackage.scripts.deploy === 'undefined') {
console.log();
if (useYarn) {
console.log(` ${chalk.cyan('yarn')} add --dev gh-pages`);
} else {
console.log(` ${chalk.cyan('npm')} install --save-dev gh-pages`);
}
console.log();
console.log(
`Add the following script in your ${chalk.cyan('package.json')}.`
);
console.log();
console.log(` ${chalk.dim('// ...')}`);
console.log(` ${chalk.yellow('"scripts"')}: {`);
console.log(` ${chalk.dim('// ...')}`);
console.log(
` ${chalk.yellow('"predeploy"')}: ${chalk.yellow('"npm run build",')}`
);
console.log(
` ${chalk.yellow('"deploy"')}: ${chalk.yellow('"gh-pages -d build"')}`
);
console.log(' }');
console.log();
console.log('Then run:');
}
console.log();
console.log(` ${chalk.cyan(useYarn ? 'yarn' : 'npm')} run deploy`);
console.log();
} else if (publicPath !== '/') {
// "homepage": "http://mywebsite.com/project"
console.log(
`The project was built assuming it is hosted at ${chalk.green(publicPath)}.`
);
console.log(
`You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.`
);
console.log();
console.log(`The ${chalk.cyan('build')} folder is ready to be deployed.`);
console.log();
} else {
if (publicUrl) {
// "homepage": "http://mywebsite.com"
console.log(
`The project was built assuming it is hosted at ${chalk.green(publicUrl)}.`
);
console.log(
`You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.`
);
console.log();
} else {
// no homepage
console.log(
'The project was built assuming it is hosted at the server root.'
);
console.log(
`To override this, specify the ${chalk.green('homepage')} in your ${chalk.cyan('package.json')}.`
);
console.log('For example, add this to build it for GitHub Pages:');
console.log();
console.log(
` ${chalk.green('"homepage"')} ${chalk.cyan(':')} ${chalk.green('"http://myname.github.io/myapp"')}${chalk.cyan(',')}`
);
console.log();
}
console.log(
`The ${chalk.cyan(buildFolder)} folder is ready to be deployed.`
);
console.log('You may serve it with a static server:');
console.log();
if (useYarn) {
console.log(` ${chalk.cyan('yarn')} global add serve`);
} else {
console.log(` ${chalk.cyan('npm')} install -g serve`);
}
console.log(` ${chalk.cyan('serve')} -s build`);
console.log();
}
}

module.exports = printHostingInstructions;
Loading