diff --git a/client/.eslintrc.js b/client/.eslintrc.js index e8e151c..c17b153 100644 --- a/client/.eslintrc.js +++ b/client/.eslintrc.js @@ -41,7 +41,8 @@ module.exports = { 'eol-last': [ 'error', 'always' - ] + ], + '@typescript-eslint/no-var-requires': 0, }, 'settings': { 'react': { diff --git a/client/package-lock.json b/client/package-lock.json index 08a9e67..87abcb4 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -72,6 +72,7 @@ "webpack-dev-middleware": "^5.3.1", "webpack-dev-server": "^4.8.1", "webpack-hot-middleware": "^2.25.1", + "webpack-node-externals": "^3.0.0", "workbox-webpack-plugin": "^6.5.3", "workbox-window": "^6.5.3" } @@ -11088,6 +11089,15 @@ "node": ">=10.0.0" } }, + "node_modules/webpack-node-externals": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", + "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", @@ -19593,6 +19603,12 @@ "wildcard": "^2.0.0" } }, + "webpack-node-externals": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", + "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", + "dev": true + }, "webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", diff --git a/client/package.json b/client/package.json index ec08b51..7c45685 100644 --- a/client/package.json +++ b/client/package.json @@ -4,7 +4,7 @@ "description": "Starter Kit de server side render de react", "main": "src/server/index", "scripts": { - "start": "ts-node src/server", + "start": "node build/server/app-server.js", "start:dev": "nodemon --exec 'ts-node' src/server/index -e js,json,ts,tsx,jsx", "build": "webpack-cli --config webpack.config.js", "lint": "eslint ./ --ext .js --ext .ts --ext .jsx --ext .tsx", @@ -89,6 +89,7 @@ "webpack-dev-middleware": "^5.3.1", "webpack-dev-server": "^4.8.1", "webpack-hot-middleware": "^2.25.1", + "webpack-node-externals": "^3.0.0", "workbox-webpack-plugin": "^6.5.3", "workbox-window": "^6.5.3" } diff --git a/client/src/server/index.js b/client/src/server/index.js index 1b6d81b..c977062 100644 --- a/client/src/server/index.js +++ b/client/src/server/index.js @@ -8,7 +8,7 @@ require('@babel/register')({ 'presets': [ '@babel/preset-env', '@babel/preset-react', - "@babel/preset-typescript", + '@babel/preset-typescript', // '@babel/preset-flow', ] }); diff --git a/client/src/server/server.js b/client/src/server/server.js index 84b0e62..5f57132 100644 --- a/client/src/server/server.js +++ b/client/src/server/server.js @@ -66,9 +66,10 @@ if(env === 'development'){ } const setResponse = (html, preloadedState, manifest) => { - const mainStyles = manifest ? manifest['main.css'] : 'assets/app.css'; - const mainBuild = manifest ? manifest['main.js'] : 'assets/app.js'; + const mainStyles = manifest ? manifest['frontend.css'] : 'assets/app.css'; + const mainBuild = manifest ? manifest['frontend.js'] : 'assets/app.js'; const vendorBuild = manifest ? manifest['vendors.js'] : 'assets/vendor.js'; + const manifestJson = manifest ? `` : ''; return(` @@ -79,7 +80,7 @@ const setResponse = (html, preloadedState, manifest) => { - + ${manifestJson} App diff --git a/client/webpack.config.js b/client/webpack.config.js index 26403e3..fb0dbfd 100644 --- a/client/webpack.config.js +++ b/client/webpack.config.js @@ -10,13 +10,114 @@ const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const ESLintPlugin = require('eslint-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin'); const { InjectManifest } = require('workbox-webpack-plugin'); +const nodeExternals = require('webpack-node-externals'); const PUBLIC_URL = process.env.PUBLIC_URL || '/'; -module.exports = { - entry: './src/frontend/index.tsx', +const frontendConfig = { + entry: { + frontend: './src/frontend/index.tsx', + }, output: { path: path.resolve(__dirname, 'build'), - filename: 'assets/app-[fullhash].js', + filename: 'assets/app-[name]-[fullhash].js', + publicPath: PUBLIC_URL, + }, + resolve: { + extensions: ['.js', '.jsx','.ts','.tsx', '.json'], + alias: { + '@components': path.resolve(__dirname, 'src/frontend/components/'), + '@styles': path.resolve(__dirname, 'src/frontend/styles/'), + } + }, + mode: 'production', + module: { + rules: [ + { + test: /\.(js|jsx|ts|tsx)$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + }, + }, + { + test: /\.(css|sass|scss)$/, + use: [ + MiniCssExtractPlugin.loader, + 'css-loader', + 'sass-loader', + ], + }, + ], + }, + plugins: [ + new CompressionWebpackPlugin({ + test: /\.(js|css)$/, + filename: '[path][base].gz', + }), + new MiniCssExtractPlugin({ + filename: 'assets/app-[fullhash].css', + }), + new WebpackManifestPlugin({ + fileName: 'assets/manifest-hash.json', + }), + new CleanWebpackPlugin({ + cleanOnceBeforeBuildPatterns: [ + '**/*', + '!server/**', + ], + }), + new ESLintPlugin(), + new webpack.DefinePlugin({ + 'process.env': JSON.stringify(dotenv.parsed), + 'process.env.PUBLIC_URL': JSON.stringify(PUBLIC_URL), + }), + new CopyPlugin({ + patterns: [ + { + from: './public/manifest.json', to: '', + } + ] + }), + new InjectManifest({ + swSrc: './service-worker.js', + swDest: 'service-worker.js', + }), + ], + optimization: { + minimize: true, + minimizer: [ + new CssMinimizerPlugin(), + new TerserPlugin(), + ], + splitChunks: { + chunks: 'async', + cacheGroups: { + vendors: { + name: 'vendors', + chunks: 'all', + reuseExistingChunk: true, + priority: 1, + filename: 'assets/vendor-[name]-[fullhash].js', + enforce: true, + test (module, chunks){ + const name = module.nameForCondition && module.nameForCondition(); + return chunks.name !== 'vendors' && /[\\/]node_modules[\\/]/.test(name); + }, + }, + }, + }, + }, +}; + +const serverConfig = { + entry: { + server: './src/server/index.js', + }, + target: "node", + externals: [nodeExternals()], + output: { + path: path.resolve(__dirname, 'build'), + filename: 'server/app-[name].js', publicPath: PUBLIC_URL, }, resolve: { @@ -89,7 +190,7 @@ module.exports = { chunks: 'all', reuseExistingChunk: true, priority: 1, - filename: 'assets/vendor-[fullhash].js', + filename: 'assets/vendor-[name]-[fullhash].js', enforce: true, test (module, chunks){ const name = module.nameForCondition && module.nameForCondition(); @@ -100,3 +201,5 @@ module.exports = { }, }, }; + + module.exports = [frontendConfig, serverConfig];