Skip to content
This repository was archived by the owner on Jan 18, 2024. It is now read-only.

Updated webpack-config #409

Merged
merged 2 commits into from
Mar 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions packages/webpack-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"@babel/core": "^7.0.0",
"@babel/polyfill": "^7.2.5",
"babel-loader": "^8.0.5",
"babel-preset-expo": "^5.0.0",
"brotli-webpack-plugin": "^1.1.0",
"case-sensitive-paths-webpack-plugin": "^2.2.0",
"clean-webpack-plugin": "^1.0.1",
Expand All @@ -24,7 +23,6 @@
"pnp-webpack-plugin": "^1.2.1",
"progress-bar-webpack-plugin": "^1.12.1",
"react-dev-utils": "^7.0.3",
"terser-webpack-plugin": "^1.2.2",
"url-loader": "^1.1.2",
"webpack": "4.24.0",
"webpack-bundle-analyzer": "^3.0.4",
Expand Down
6 changes: 5 additions & 1 deletion packages/webpack-config/web-default/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
body,
#main {
height: 100%;
margin: 0px;
padding: 0px;
}
#main {
display: flex;
Expand All @@ -31,10 +33,12 @@
<div id="main"></div>

<script>
if ('serviceWorker' in navigator)
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}
</script>

</body>
</html>
6 changes: 4 additions & 2 deletions packages/webpack-config/webpack/createIndexHTMLFromAppJSON.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ function createIndexHTMLFromAppJSON(locations) {

const { expo: expoManifest = {} } = nativeAppManifest;

const color = expoManifest.primaryColor || '#000000';

const metaTags = {
viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no',
description: expoManifest.description || 'A Neat Expo App',
'theme-color': expoManifest.primaryColor || '#000000',
'theme-color': color,
'apple-mobile-web-app-capable': 'yes',
// default, black, black-translucent
'apple-mobile-web-app-status-bar-style': 'default',
'apple-mobile-web-app-title': expoManifest.name,
'application-name': expoManifest.name,
// Windows
'msapplication-navbutton-color': '',
'msapplication-navbutton-color': color,
'msapplication-TileColor': '',
'msapplication-TileImage': '',
};
Expand Down
30 changes: 5 additions & 25 deletions packages/webpack-config/webpack/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const WebpackDeepScopeAnalysisPlugin = require('webpack-deep-scope-plugin').default;
const getLocations = require('./webpackLocations');
const createIndexHTMLFromAppJSON = require('./createIndexHTMLFromAppJSON');
const createClientEnvironment = require('./createClientEnvironment');
Expand Down Expand Up @@ -83,7 +84,7 @@ module.exports = function(env) {
const nativeAppManifest = require(locations.appJson);

const ttfLoaderConfiguration = {
test: /\.ttf$/,
test: /\.(ttf|otf)$/,
use: [
{
loader: 'url-loader',
Expand All @@ -106,24 +107,7 @@ module.exports = function(env) {
exclude: locations.template.folder,
};

// This method intercepts modules being referenced in react-native
// and redirects them to web friendly versions in expo.
function getWebModule(initialRoot, moduleName) {
return function(res) {
if (res.context.includes('node_modules/react-native/')) {
res.request = locations.includeModule(initialRoot + moduleName);
}
};
}

function useWebModule(modulePathToHiJack, redirectPath, initialRoot = 'expo/build/web/') {
return new webpack.NormalModuleReplacementPlugin(
new RegExp(modulePathToHiJack),
getWebModule(initialRoot, redirectPath)
);
}

const publicPath = '/';
const publicPath = ''.replace(/\/$/, '');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just an empty string '', is that on purpose?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may be adding publicUrl for export right? If so then this will prevent // in the index.html. This looks a little strange out of context because I split it into 2 PRs.


return {
context: __dirname,
Expand Down Expand Up @@ -160,13 +144,9 @@ module.exports = function(env) {
fileName: 'asset-manifest.json',
publicPath,
}),

new webpack.DefinePlugin(clientEnv),

useWebModule('Performance/Systrace', 'Performance/Systrace'),
useWebModule('RCTNetworking', 'Network/RCTNetworking'),
useWebModule('Platform', 'Utilities/Platform'),
useWebModule('HMRLoadingView', 'Utilities/HMRLoadingView'),
// Remove unused import/exports
new WebpackDeepScopeAnalysisPlugin(),

new WorkboxPlugin.GenerateSW({
skipWaiting: true,
Expand Down
110 changes: 11 additions & 99 deletions packages/webpack-config/webpack/webpack.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ const merge = require('webpack-merge');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const BrotliPlugin = require('brotli-webpack-plugin');
const WebpackDeepScopeAnalysisPlugin = require('webpack-deep-scope-plugin').default;

const common = require('./webpack.common.js');
const getLocations = require('./webpackLocations');
Expand All @@ -24,131 +22,45 @@ module.exports = function(env = {}) {
return merge(common(env), {
mode: 'production',
entry: {
vendor: ['react', 'react-native-web'],
app: appEntry,
},
devtool: 'source-map',
plugins: [
/** Delete the build folder */
// Delete the build folder
new CleanWebpackPlugin([locations.production.folder], {
root: locations.root,
verbose: true,
dry: false,
}),
/** Remove unused import/exports */
new WebpackDeepScopeAnalysisPlugin(),

new CopyWebpackPlugin([
{
from: locations.template.folder,
to: locations.production.folder,
ignore: 'index.html',
},
]),

new MiniCssExtractPlugin({
filename: 'static/css/[contenthash].css',
chunkFilename: 'static/css/[contenthash].chunk.css',
}),

/** GZIP files */
// GZIP files
new CompressionPlugin({
test: /\.(js|css)$/,
filename: '[path].gz[query]',
algorithm: 'gzip',
threshold: 1024,
minRatio: 0.8,
}),
/** secondary compression for platforms that load .br */
// secondary compression for platforms that load .br
new BrotliPlugin({
asset: '[path].br[query]',
test: /\.(js|css)$/,
threshold: 1024,
minRatio: 0.8,
}),

/** Copy the PWA manifest.json and the caching policy serve.json from the template folder to the build folder */
new CopyWebpackPlugin([
{
from: locations.template.manifest,
to: locations.production.manifest,
},
{
from: locations.template.serveJson,
to: locations.production.serveJson,
},
]),
],
optimization: {
usedExports: true,
concatenateModules: true,
occurrenceOrder: true,
minimize: true,
minimizer: [
new TerserPlugin({
cache: true,
sourceMap: true,
parallel: true,
extractComments: 'all',
terserOptions: {
warnings: false,
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
module: false,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
},
}),
],
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
maxAsyncRequests: 5,
minSize: 0,
maxSize: 0,
minChunks: Infinity,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendor: {
chunks: 'all',
priority: -10,
test: /[\\/]node_modules[\\/]/,
// name of the chunk
name(module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];

// npm package names are URL-safe, but some servers don't like @ symbols
return `npm.${packageName.replace('@', '')}`;
},
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 2,
priority: 10,
reuseExistingChunk: true,
enforce: true,
},
},
},
},
});
};
Loading