From d295979fc288f60932c2415ab2e62de0a603f5aa Mon Sep 17 00:00:00 2001 From: Andrey Popp <8mayday@gmail.com> Date: Sat, 13 Aug 2016 00:37:54 +0300 Subject: [PATCH] Load favicon through html-loader. (#428) * Load favicon through html-loader. Fixes #291. * Add test for *.ico in e2e test suite * Configure html-loader to process * Address feedback on html-loader inclusion. * Place favicon.ico at the root of the build dir * Make comment style consistent between prod and dev webpack configs * Fix html-loader config in dev mode --- config/paths.js | 3 --- config/webpack.config.dev.js | 22 ++++++++++++++++++++-- config/webpack.config.prod.js | 30 ++++++++++++++++++++++++------ package.json | 1 + tasks/e2e.sh | 3 +++ template/index.html | 1 + template/{ => src}/favicon.ico | Bin 7 files changed, 49 insertions(+), 11 deletions(-) rename template/{ => src}/favicon.ico (100%) diff --git a/config/paths.js b/config/paths.js index 4db5873d29a..cb899651c22 100644 --- a/config/paths.js +++ b/config/paths.js @@ -36,7 +36,6 @@ if (isInCreateReactAppSource) { module.exports = { appBuild: resolveOwn('../build'), appHtml: resolveOwn('../template/index.html'), - appFavicon: resolveOwn('../template/favicon.ico'), appPackageJson: resolveOwn('../package.json'), appStatic: resolveOwn('../template/static'), appSrc: resolveOwn('../template/src'), @@ -48,7 +47,6 @@ if (isInCreateReactAppSource) { module.exports = { appBuild: resolveApp('build'), appHtml: resolveApp('index.html'), - appFavicon: resolveApp('favicon.ico'), appPackageJson: resolveApp('package.json'), appStatic: resolveApp('static'), appSrc: resolveApp('src'), @@ -61,7 +59,6 @@ if (isInCreateReactAppSource) { module.exports = { appBuild: resolveApp('build'), appHtml: resolveApp('index.html'), - appFavicon: resolveApp('favicon.ico'), appPackageJson: resolveApp('package.json'), appStatic: resolveApp('static'), appSrc: resolveApp('src'), diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index 4edc5c2ea62..1cc59e6640a 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -127,13 +127,23 @@ module.exports = { // When you `import` an asset, you get its (virtual) filename. // In production, they would get copied to the `build` folder. { - test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, + test: /\.(ico|jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, include: [paths.appSrc, paths.appNodeModules], + exclude: /\/favicon.ico$/, loader: 'file', query: { name: 'static/media/[name].[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. { @@ -144,6 +154,15 @@ module.exports = { limit: 10000, name: 'static/media/[name].[ext]' } + }, + // "html" loader is used to process template page (index.html) to resolve + // resources linked with HTML tags. + { + test: /\.html$/, + loader: 'html', + query: { + attrs: ['link:href'], + } } ] }, @@ -170,7 +189,6 @@ module.exports = { new HtmlWebpackPlugin({ inject: true, template: paths.appHtml, - favicon: paths.appFavicon, }), // Copy the static folder as-is to the build folder new CopyWebpackPlugin([ diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index 891fae7fbe7..ac60cd711e8 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -127,23 +127,33 @@ module.exports = { loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss') // Note: this won't work without `new ExtractTextPlugin()` in `plugins`. }, + // JSON is not enabled by default in Webpack but both Node and Browserify + // allow it implicitly so we also enable it. { - // JSON is not enabled by default in Webpack but both Node and Browserify - // allow it implicitly so we also enable it. test: /\.json$/, include: [paths.appSrc, paths.appNodeModules], loader: 'json' }, + // "file" loader makes sure those assets end up in the `build` folder. + // When you `import` an asset, you get its filename. { - // "file" loader makes sure those assets end up in the `build` folder. - // When you `import` an asset, you get its filename. - test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, + test: /\.(ico|jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, + exclude: /\/favicon.ico$/, include: [paths.appSrc, paths.appNodeModules], 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. { @@ -154,6 +164,15 @@ 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 HTML tags. + { + test: /\.html$/, + loader: 'html', + query: { + attrs: ['link:href'], + } } ] }, @@ -182,7 +201,6 @@ module.exports = { new HtmlWebpackPlugin({ inject: true, template: paths.appHtml, - favicon: paths.appFavicon, minify: { removeComments: true, collapseWhitespace: true, diff --git a/package.json b/package.json index 73d09034f82..57961dc17d6 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "filesize": "3.3.0", "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.0", "jest": "14.1.0", diff --git a/tasks/e2e.sh b/tasks/e2e.sh index a1566a85bdb..6e6c20c9420 100755 --- a/tasks/e2e.sh +++ b/tasks/e2e.sh @@ -67,6 +67,7 @@ test -e build/*.html test -e build/static/js/*.js test -e build/static/css/*.css test -e build/static/media/*.svg +test -e build/favicon.ico # Run tests npm run test @@ -96,6 +97,7 @@ test -e build/*.html test -e build/static/js/*.js test -e build/static/css/*.css test -e build/static/media/*.svg +test -e build/favicon.ico # Run tests npm run test @@ -113,6 +115,7 @@ test -e build/*.html test -e build/static/js/*.js test -e build/static/css/*.css test -e build/static/media/*.svg +test -e build/favicon.ico # Run tests npm run test diff --git a/template/index.html b/template/index.html index 72e10e94c6c..f89671553eb 100644 --- a/template/index.html +++ b/template/index.html @@ -3,6 +3,7 @@
+