Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Meta
create-react-app
Commits
bc6392af
Commit
bc6392af
authored
8 years ago
by
Dan Abramov
Committed by
GitHub
8 years ago
Browse files
Options
Download
Email Patches
Plain Diff
Add support for public/ folder (#703)
parent
5b85a362
No related merge requests found
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
packages/react-scripts/config/paths.js
+6
-3
packages/react-scripts/config/paths.js
packages/react-scripts/config/webpack.config.dev.js
+21
-23
packages/react-scripts/config/webpack.config.dev.js
packages/react-scripts/config/webpack.config.prod.js
+34
-29
packages/react-scripts/config/webpack.config.prod.js
packages/react-scripts/package.json
+0
-1
packages/react-scripts/package.json
packages/react-scripts/scripts/build.js
+11
-1
packages/react-scripts/scripts/build.js
packages/react-scripts/scripts/eject.js
+2
-0
packages/react-scripts/scripts/eject.js
packages/react-scripts/scripts/start.js
+15
-17
packages/react-scripts/scripts/start.js
packages/react-scripts/scripts/test.js
+1
-0
packages/react-scripts/scripts/test.js
packages/react-scripts/scripts/utils/InterpolateHtmlPlugin.js
+43
-0
...ages/react-scripts/scripts/utils/InterpolateHtmlPlugin.js
packages/react-scripts/scripts/utils/getClientEnvironment.js
+38
-0
packages/react-scripts/scripts/utils/getClientEnvironment.js
packages/react-scripts/template/public/favicon.ico
+0
-0
packages/react-scripts/template/public/favicon.ico
packages/react-scripts/template/public/index.html
+31
-0
packages/react-scripts/template/public/index.html
with
202 additions
and
74 deletions
+202
-74
packages/react-scripts/config/paths.js
+
6
-
3
View file @
bc6392af
...
...
@@ -38,7 +38,8 @@ var nodePaths = (process.env.NODE_PATH || '')
// config after eject: we're in ./config/
module
.
exports
=
{
appBuild
:
resolveApp
(
'
build
'
),
appHtml
:
resolveApp
(
'
index.html
'
),
appPublic
:
resolveApp
(
'
public
'
),
appHtml
:
resolveApp
(
'
public/index.html
'
),
appIndexJs
:
resolveApp
(
'
src/index.js
'
),
appPackageJson
:
resolveApp
(
'
package.json
'
),
appSrc
:
resolveApp
(
'
src
'
),
...
...
@@ -56,7 +57,8 @@ function resolveOwn(relativePath) {
// config before eject: we're in ./node_modules/react-scripts/config/
module
.
exports
=
{
appBuild
:
resolveApp
(
'
build
'
),
appHtml
:
resolveApp
(
'
index.html
'
),
appPublic
:
resolveApp
(
'
public
'
),
appHtml
:
resolveApp
(
'
public/index.html
'
),
appIndexJs
:
resolveApp
(
'
src/index.js
'
),
appPackageJson
:
resolveApp
(
'
package.json
'
),
appSrc
:
resolveApp
(
'
src
'
),
...
...
@@ -71,7 +73,8 @@ module.exports = {
// @remove-on-publish-begin
module
.
exports
=
{
appBuild
:
resolveOwn
(
'
../../../build
'
),
appHtml
:
resolveOwn
(
'
../template/index.html
'
),
appPublic
:
resolveOwn
(
'
../template/public
'
),
appHtml
:
resolveOwn
(
'
../template/public/index.html
'
),
appIndexJs
:
resolveOwn
(
'
../template/src/index.js
'
),
appPackageJson
:
resolveOwn
(
'
../package.json
'
),
appSrc
:
resolveOwn
(
'
../template/src
'
),
...
...
This diff is collapsed.
Click to expand it.
packages/react-scripts/config/webpack.config.dev.js
+
21
-
23
View file @
bc6392af
...
...
@@ -14,9 +14,20 @@ var autoprefixer = require('autoprefixer');
var
webpack
=
require
(
'
webpack
'
);
var
HtmlWebpackPlugin
=
require
(
'
html-webpack-plugin
'
);
var
CaseSensitivePathsPlugin
=
require
(
'
case-sensitive-paths-webpack-plugin
'
);
var
InterpolateHtmlPlugin
=
require
(
'
../scripts/utils/InterpolateHtmlPlugin
'
);
var
WatchMissingNodeModulesPlugin
=
require
(
'
../scripts/utils/WatchMissingNodeModulesPlugin
'
);
var
getClientEnvironment
=
require
(
'
../scripts/utils/getClientEnvironment
'
);
var
paths
=
require
(
'
./paths
'
);
var
env
=
require
(
'
./env
'
);
// Webpack uses `publicPath` to determine where the app is being served from.
// In development, we always serve from the root. This makes config easier.
var
publicPath
=
'
/
'
;
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing shlash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
var
publicUrl
=
''
;
// Get enrivonment variables to inject into our app.
var
env
=
getClientEnvironment
(
publicUrl
);
// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
...
...
@@ -63,8 +74,8 @@ module.exports = {
// served by WebpackDevServer in development. This is the JS bundle
// containing code from all our entry points, and the Webpack runtime.
filename
:
'
static/js/bundle.js
'
,
//
In development, we alway
s serve from
the root. This makes config easier
.
publicPath
:
'
/
'
//
This is the URL that app i
s serve
d
from
. We use "/" in development
.
publicPath
:
publicPath
},
resolve
:
{
// This allows you to set a fallback for where Webpack should look for modules.
...
...
@@ -129,21 +140,11 @@ module.exports = {
// In production, they would get copied to the `build` folder.
{
test
:
/
\.(
ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2
)(\?
.*
)?
$/
,
exclude
:
/
\/
favicon.ico$/
,
loader
:
'
file
'
,
query
:
{
name
:
'
static/media/[name].[hash:8].[ext]
'
}
},
// A special case for favicon.ico to place it into build root directory.
{
test
:
/
\/
favicon.ico$/
,
include
:
[
paths
.
appSrc
],
loader
:
'
file
'
,
query
:
{
name
:
'
favicon.ico?[hash:8]
'
}
},
// "url" loader works just like "file" loader but it also embeds
// assets smaller than specified size as data URLs to avoid requests.
{
...
...
@@ -153,15 +154,6 @@ module.exports = {
limit
:
10000
,
name
:
'
static/media/[name].[hash:8].[ext]
'
}
},
// "html" loader is used to process template page (index.html) to resolve
// resources linked with <link href="./relative/path"> HTML tags.
{
test
:
/
\.
html$/
,
loader
:
'
html
'
,
query
:
{
attrs
:
[
'
link:href
'
],
}
}
]
},
...
...
@@ -186,13 +178,19 @@ module.exports = {
];
},
plugins
:
[
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In development, this will be an empty string.
new
InterpolateHtmlPlugin
({
PUBLIC_URL
:
publicUrl
}),
// Generates an `index.html` file with the <script> injected.
new
HtmlWebpackPlugin
({
inject
:
true
,
template
:
paths
.
appHtml
,
}),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'development') { ... }.
See `env.js`.
// if (process.env.NODE_ENV === 'development') { ... }.
new
webpack
.
DefinePlugin
(
env
),
// This is necessary to emit hot updates (currently CSS only):
new
webpack
.
HotModuleReplacementPlugin
(),
...
...
This diff is collapsed.
Click to expand it.
packages/react-scripts/config/webpack.config.prod.js
+
34
-
29
View file @
bc6392af
...
...
@@ -16,12 +16,18 @@ var HtmlWebpackPlugin = require('html-webpack-plugin');
var
ExtractTextPlugin
=
require
(
'
extract-text-webpack-plugin
'
);
var
url
=
require
(
'
url
'
);
var
paths
=
require
(
'
./paths
'
);
var
env
=
require
(
'
./env
'
);
var
InterpolateHtmlPlugin
=
require
(
'
../scripts/utils/InterpolateHtmlPlugin
'
);
var
getClientEnvironment
=
require
(
'
../scripts/utils/getClientEnvironment
'
);
// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
if
(
env
[
'
process.env.NODE_ENV
'
]
!==
'
"production"
'
)
{
throw
new
Error
(
'
Production builds must have NODE_ENV=production.
'
);
function
ensureSlash
(
path
,
needsSlash
)
{
var
hasSlash
=
path
.
endsWith
(
'
/
'
);
if
(
hasSlash
&&
!
needsSlash
)
{
return
path
.
substr
(
path
,
path
.
length
-
1
);
}
else
if
(
!
hasSlash
&&
needsSlash
)
{
return
path
+
'
/
'
;
}
else
{
return
path
;
}
}
// We use "homepage" field to infer "public path" at which the app is served.
...
...
@@ -30,10 +36,21 @@ if (env['process.env.NODE_ENV'] !== '"production"') {
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
var
homepagePath
=
require
(
paths
.
appPackageJson
).
homepage
;
var
publicPath
=
homepagePath
?
url
.
parse
(
homepagePath
).
pathname
:
'
/
'
;
if
(
!
publicPath
.
endsWith
(
'
/
'
))
{
// If we don't do this, file assets will get incorrect paths.
publicPath
+=
'
/
'
;
var
homepagePathname
=
homepagePath
?
url
.
parse
(
homepagePath
).
pathname
:
'
/
'
;
// Webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
var
publicPath
=
ensureSlash
(
homepagePathname
,
true
);
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing shlash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
var
publicUrl
=
ensureSlash
(
homepagePathname
,
false
);
// Get enrivonment variables to inject into our app.
var
env
=
getClientEnvironment
(
publicUrl
);
// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
if
(
env
[
'
process.env.NODE_ENV
'
]
!==
'
"production"
'
)
{
throw
new
Error
(
'
Production builds must have NODE_ENV=production.
'
);
}
// This is the production configuration.
...
...
@@ -139,21 +156,11 @@ module.exports = {
// When you `import` an asset, you get its filename.
{
test
:
/
\.(
ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2
)(\?
.*
)?
$/
,
exclude
:
/
\/
favicon.ico$/
,
loader
:
'
file
'
,
query
:
{
name
:
'
static/media/[name].[hash:8].[ext]
'
}
},
// A special case for favicon.ico to place it into build root directory.
{
test
:
/
\/
favicon.ico$/
,
include
:
[
paths
.
appSrc
],
loader
:
'
file
'
,
query
:
{
name
:
'
favicon.ico?[hash:8]
'
}
},
// "url" loader works just like "file" loader but it also embeds
// assets smaller than specified size as data URLs to avoid requests.
{
...
...
@@ -163,15 +170,6 @@ module.exports = {
limit
:
10000
,
name
:
'
static/media/[name].[hash:8].[ext]
'
}
},
// "html" loader is used to process template page (index.html) to resolve
// resources linked with <link href="./relative/path"> HTML tags.
{
test
:
/
\.
html$/
,
loader
:
'
html
'
,
query
:
{
attrs
:
[
'
link:href
'
],
}
}
]
},
...
...
@@ -198,6 +196,13 @@ module.exports = {
];
},
plugins
:
[
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In production, it will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new
InterpolateHtmlPlugin
({
PUBLIC_URL
:
publicUrl
}),
// Generates an `index.html` file with the <script> injected.
new
HtmlWebpackPlugin
({
inject
:
true
,
...
...
@@ -216,7 +221,7 @@ module.exports = {
}
}),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }.
See `env.js`.
// if (process.env.NODE_ENV === 'production') { ... }.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new
webpack
.
DefinePlugin
(
env
),
...
...
This diff is collapsed.
Click to expand it.
packages/react-scripts/package.json
+
0
-
1
View file @
bc6392af
...
...
@@ -46,7 +46,6 @@
"find-cache-dir"
:
"0.1.1"
,
"fs-extra"
:
"0.30.0"
,
"gzip-size"
:
"3.0.0"
,
"html-loader"
:
"0.4.3"
,
"html-webpack-plugin"
:
"2.22.0"
,
"http-proxy-middleware"
:
"0.17.1"
,
"jest"
:
"15.1.1"
,
...
...
This diff is collapsed.
Click to expand it.
packages/react-scripts/scripts/build.js
+
11
-
1
View file @
bc6392af
...
...
@@ -13,7 +13,7 @@
process
.
env
.
NODE_ENV
=
'
production
'
;
var
chalk
=
require
(
'
chalk
'
);
var
fs
=
require
(
'
fs
'
);
var
fs
=
require
(
'
fs
-extra
'
);
var
path
=
require
(
'
path
'
);
var
filesize
=
require
(
'
filesize
'
);
var
gzipSize
=
require
(
'
gzip-size
'
).
sync
;
...
...
@@ -70,6 +70,9 @@ recursive(paths.appBuild, (err, fileNames) => {
// Start the webpack build
build
(
previousSizeMap
);
// Merge with the public folder
copyPublicFolder
();
});
// Print a detailed summary of build files.
...
...
@@ -175,3 +178,10 @@ function build(previousSizeMap) {
}
});
}
function
copyPublicFolder
()
{
fs
.
copySync
(
paths
.
appPublic
,
paths
.
appBuild
,
{
dereference
:
true
,
filter
:
file
=>
file
!==
paths
.
appHtml
});
}
This diff is collapsed.
Click to expand it.
packages/react-scripts/scripts/eject.js
+
2
-
0
View file @
bc6392af
...
...
@@ -46,6 +46,8 @@ prompt(
path
.
join
(
'
scripts
'
,
'
start.js
'
),
path
.
join
(
'
scripts
'
,
'
utils
'
,
'
checkRequiredFiles.js
'
),
path
.
join
(
'
scripts
'
,
'
utils
'
,
'
chrome.applescript
'
),
path
.
join
(
'
scripts
'
,
'
utils
'
,
'
getClientEnvironment.js
'
),
path
.
join
(
'
scripts
'
,
'
utils
'
,
'
InterpolateHtmlPlugin.js
'
),
path
.
join
(
'
scripts
'
,
'
utils
'
,
'
prompt.js
'
),
path
.
join
(
'
scripts
'
,
'
utils
'
,
'
WatchMissingNodeModulesPlugin.js
'
)
];
...
...
This diff is collapsed.
Click to expand it.
packages/react-scripts/scripts/start.js
+
15
-
17
View file @
bc6392af
...
...
@@ -255,23 +255,21 @@ function runDevServer(port, protocol) {
// Silence WebpackDevServer's own logs since they're generally not useful.
// It will still show compile warnings and errors with this setting.
clientLogLevel
:
'
none
'
,
// By default WebpackDevServer also serves files from the current directory.
// This might be useful in legacy apps. However we already encourage people
// to use Webpack for importing assets in the code, so we don't need to
// additionally serve files by their filenames. Otherwise, even if it
// works in development, those files will be missing in production, unless
// we explicitly copy them. But even if we copy all the files into
// the build output (which doesn't seem to be wise because it may contain
// private information such as files with API keys, for example), we would
// still have a problem. Since the filenames would be the same every time,
// browsers would cache their content, and updating file content would not
// work correctly. This is easily solved by importing assets through Webpack
// because if it can then append content hashes to filenames in production,
// just like it does for JS and CSS. And because we configured "html" loader
// to be used for HTML files, even <link href="./src/something.png"> would
// get resolved correctly by Webpack and handled both in development and
// in production without actually serving it by that path.
contentBase
:
[],
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files won’t automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_PATH%:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through Webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
contentBase
:
paths
.
appPublic
,
// Enable hot reloading server. It will provide /sockjs-node/ endpoint
// for the WebpackDevServer client so it can learn when the files were
// updated. The WebpackDevServer client is included as an entry point
...
...
This diff is collapsed.
Click to expand it.
packages/react-scripts/scripts/test.js
+
1
-
0
View file @
bc6392af
...
...
@@ -8,6 +8,7 @@
*/
process
.
env
.
NODE_ENV
=
'
test
'
;
process
.
env
.
PUBLIC_URL
=
''
;
const
createJestConfig
=
require
(
'
./utils/createJestConfig
'
);
const
jest
=
require
(
'
jest
'
);
...
...
This diff is collapsed.
Click to expand it.
packages/react-scripts/scripts/utils/InterpolateHtmlPlugin.js
0 → 100644
+
43
-
0
View file @
bc6392af
// @remove-on-eject-begin
/**
* 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.
*/
// @remove-on-eject-end
// This Webpack plugin lets us interpolate custom variables into `index.html`.
// Usage: `new InterpolateHtmlPlugin({ 'MY_VARIABLE': 42 })`
// Then, you can use %MY_VARIABLE% in your `index.html`.
// It works in tandem with HtmlWebpackPlugin.
// Learn more about creating plugins like this:
// https://github.com/ampedandwired/html-webpack-plugin#events
'
use strict
'
;
class
InterpolateHtmlPlugin
{
constructor
(
replacements
)
{
this
.
replacements
=
replacements
;
}
apply
(
compiler
)
{
compiler
.
plugin
(
'
compilation
'
,
compilation
=>
{
compilation
.
plugin
(
'
html-webpack-plugin-before-html-processing
'
,
(
data
,
callback
)
=>
{
// Run HTML through a series of user-specified string replacements.
Object
.
keys
(
this
.
replacements
).
forEach
(
key
=>
{
const
value
=
this
.
replacements
[
key
];
data
.
html
=
data
.
html
.
replace
(
'
%
'
+
key
+
'
%
'
,
value
);
});
callback
(
null
,
data
);
}
);
});
}
}
module
.
exports
=
InterpolateHtmlPlugin
;
This diff is collapsed.
Click to expand it.
packages/react-scripts/
config/env
.js
→
packages/react-scripts/
scripts/utils/getClientEnvironment
.js
+
38
-
0
View file @
bc6392af
...
...
@@ -13,14 +13,26 @@
// injected into the application via DefinePlugin in Webpack configuration.
var
REACT_APP
=
/^REACT_APP_/i
;
var
NODE_ENV
=
JSON
.
stringify
(
process
.
env
.
NODE_ENV
||
'
development
'
);
module
.
exports
=
Object
.
keys
(
process
.
env
)
.
filter
(
key
=>
REACT_APP
.
test
(
key
))
.
reduce
((
env
,
key
)
=>
{
env
[
'
process.env.
'
+
key
]
=
JSON
.
stringify
(
process
.
env
[
key
]);
return
env
;
},
{
'
process.env.NODE_ENV
'
:
NODE_ENV
});
function
getClientEnvironment
(
publicUrl
)
{
return
Object
.
keys
(
process
.
env
)
.
filter
(
key
=>
REACT_APP
.
test
(
key
))
.
reduce
((
env
,
key
)
=>
{
env
[
'
process.env.
'
+
key
]
=
JSON
.
stringify
(
process
.
env
[
key
]);
return
env
;
},
{
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
'
process.env.NODE_ENV
'
:
JSON
.
stringify
(
process
.
env
.
NODE_ENV
||
'
development
'
),
// Useful for resolving the correct path to static assets in `public`.
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
// This should only be used as an escape hatch. Normally you would put
// images into the `src` and `import` them in code to get their paths.
'
process.env.PUBLIC_URL
'
:
JSON
.
stringify
(
publicUrl
)
});
}
module
.
exports
=
getClientEnvironment
;
This diff is collapsed.
Click to expand it.
packages/react-scripts/template/
sr
c/favicon.ico
→
packages/react-scripts/template/
publi
c/favicon.ico
+
0
-
0
View file @
bc6392af
File moved
This diff is collapsed.
Click to expand it.
packages/react-scripts/template/index.html
→
packages/react-scripts/template/
public/
index.html
+
31
-
0
View file @
bc6392af
...
...
@@ -3,7 +3,16 @@
<head>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1"
>
<link
rel=
"shortcut icon"
href=
"./src/favicon.ico"
>
<link
rel=
"shortcut icon"
href=
"%PUBLIC_URL%/favicon.ico"
>
<!--
Notice the use of %PUBLIC_URL% in the tag above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favico.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>
React App
</title>
</head>
<body>
...
...
@@ -15,7 +24,7 @@
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start`
in this folder
.
To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
</body>
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment