How to fix "Uncaught TypeError: Cannot read property 'call' of undefined" in webpack? - webpack-dev-server

Basically I'm setting up webpack and when I tried getting dev-server in development mode in webpack, I ran into this Error.
I tried following some instructions in other things, tried from beginning twice, but still getting the same error. I can't figure out what I am doing wrong here. If anyone has solution onto this issue, I'd very much appreciate that. Thanks.
Error I'm getting:
bundle.js:20 Uncaught TypeError: Cannot read property 'call' of undefined
at __webpack_require__ (bundle.js:20)
at eval (index.js:2)
at Object../src/js/index.js (bundle.js:357)
at __webpack_require__ (bundle.js:20)
at eval (webpack:///multi_(:8080/webpack)-dev-server/client?:2:18)
at Object.0 (bundle.js:368)
at __webpack_require__ (bundle.js:20)
at bundle.js:69
at bundle.js:72
Specifics of error:
// Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
webpack.config.js:
const path = require('path');
module.exports = {
entry: './src/js/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/bundle.js'
},
devServer: {
contentBase: './dist'
}
};
package.json:
{
"name": "forkify",
"version": "1.0.0",
"description": "forkify project",
"main": "index.js",
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development --open"
},
"author": "Jonas Schmedtmann",
"license": "ISC",
"devDependencies": {
"webpack": "^4.2.0"
},
"dependencies": {
"webpack-cli": "^2.1.5",
"webpack-dev-server": "^3.4.1"
}
}
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="js/bundle.js"></script>
</body>
</html>
I expect any solutions to this.

I encountered the same issue yesterday and went through a lot of discussions online. Few suggested that it is due to a bug in webpack-dev-server and few suggested it is due to improper imports of the chunks. But none of it was the case with me as I was generating a single chunk file.
What worked for me is to remove the node_modules folder completely and do a fresh npm install. Good luck.

Related

Rollup failed to resolve import "jss-plugin-{}"

I've been banging my head against this one for a while. I had my Vite ReactJS project building with no problems, and have not made significant changes. It runs fine on local, but when I use yarn build, I get the following error:
[vite]: Rollup failed to resolve import "jss-plugin-{}" from "node_modules/#material-ui/styles/esm/jssPreset/jssPreset.js".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
error during build:
Error: [vite]: Rollup failed to resolve import "jss-plugin-{}" from "node_modules/#material-ui/styles/esm/jssPreset/jssPreset.js".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
at onRollupWarning (file:///Users/ryanwalter/Dev-Repos/Pelham/liquified/node_modules/vite/dist/node/chunks/dep-557f29e6.js:45907:19)
at onwarn (file:///Users/ryanwalter/Dev-Repos/Pelham/liquified/node_modules/vite/dist/node/chunks/dep-557f29e6.js:45705:13)
at Object.onwarn (file:///Users/ryanwalter/Dev-Repos/Pelham/liquified/node_modules/rollup/dist/es/shared/rollup.js:23225:13)
at ModuleLoader.handleResolveId (file:///Users/ryanwalter/Dev-Repos/Pelham/liquified/node_modules/rollup/dist/es/shared/rollup.js:22352:26)
at file:///Users/ryanwalter/Dev-Repos/Pelham/liquified/node_modules/rollup/dist/es/shared/rollup.js:22313:26
error Command failed with exit code 1.
I've tried updating my vite.config.js file as some posts had suggested with the following:
vite config
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
define: {
"global": {},
},
resolve: {
alias: {
'./runtimeConfig': './runtimeConfig.browser',
'jss-plugin-{}': 'jss-plugin-global'
},
},
plugins: [
react()
]
})
Unfortunately, even though this does allow my app to build, I get an error in production: uncaught TypeError: {} is not a function.
Any advise here would be appreciated. I'm happy to share anything necessary.
Here's my package.json:
{
"name": "liquified",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"#aws-amplify/ui-react": "^3.5.1",
"#emotion/react": "^11.10.0",
"#emotion/styled": "^11.10.0",
"#material-ui/core": "^4.12.4",
"#mui/icons-material": "^5.8.4",
"#mui/material": "^5.10.1",
"aws-amplify": "^4.3.35",
"ethers": "^5.7.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"#types/react": "^18.0.17",
"#types/react-dom": "^18.0.6",
"#vitejs/plugin-react": "^2.1.0",
"autoprefixer": "^10.4.8",
"postcss": "^8.4.16",
"tailwindcss": "^3.1.8",
"vite": "^3.0.7"
}
}
Here's my index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Liquified App</title>
<script type="module" crossorigin src="/assets/index.671813cb.js"></script>
<link rel="stylesheet" href="/assets/index.ac81934a.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
Let me know if you need anything else. This is a tough one!
I found a solution that I don't love, but it works!
I use this vite.config.js file:
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: {
'./runtimeConfig': './runtimeConfig.browser',
},
},
plugins: [
react()
]
})
The problem is that it won't run locally with this file as I get the Uncaught ReferenceError: global is not defined error without defining global. For example, the code that works locally is:
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
// TODO: comment out before pushing to production
define: {
"global": {},
},
resolve: {
alias: {
'./runtimeConfig': './runtimeConfig.browser',
},
},
plugins: [
react()
]
})
I will just comment it out when I push to production.
Your solution is correct, yet manual changes are a bad thing especially if you want to use it in a CI/CD pipeline. A cleaner and simpler solution was provided here: https://github.com/bevacqua/dragula/issues/602#issuecomment-1109840139
<!-- your index.html -->
<script>
var global = global || window
</script>
You can find the explaination for it here: https://github.com/vitejs/vite/issues/2778#issuecomment-810086159
Vite doesn't include shims for Node variables like Webpack 4 does (in Version 5, shims also needs to be added by the user)
I like how it's explained here: https://stackoverflow.com/a/73208485/4556219
The problem is because vite doesn't define a global field in window as webpack does. And some libraries relies on it since webpack is much more older than vite.

How to exernalize #emotion/react, and #emotion/styled for Create React App

I have the following architecture:
main-frontend
foo-frontend
bar-frontend
baz-frontend
main-frontend, foo-frontend, bar-frontend and baz-frontend are all standard React apps generated using create-react-app.
All of them except main-frontend publish their UI as a React component, wrapped in a Web component. These Web components can be loaded into the main-frontend to weave all 3 sub-frontends into one super-frontend.
The problem I am facing is that in order for this approach to work, all 4 frontends have to externalize react, react-dom, react-router, and any CSS-in-JS frameworks being used.
I am able to modify Webpack configuration for create-react-app generated React apps, using the rewire package and a couple of scripts. I am reproducing these below for others facing a similar problem.
In each of foo-frontend, bar-frontend, and baz-frontend,
package.json
"dependencies": {
...
"rewire": "^6.0.0"
...
},
"scripts": {
"start": "node start.js",
"build": "node build.js",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"webpackConfig": {
"externals": {
"react": "react",
"react-dom": "react-dom",
"#emotion/react": "#emotion/react",
"#emotion/styled": "#emotion/styled"
}
}
build.js
const rewire = require('rewire');
const defaults = rewire('react-scripts/scripts/build.js');
const {
webpackConfig: {
externals
}
} = require('./package.json');
const config = defaults.__get__('config');
config.externals = externals;
start.js
const rewire = require('rewire');
const defaults = rewire('react-scripts/scripts/start.js');
const webpackConfig = require('react-scripts/config/webpack.config');
const {
webpackConfig: {
externals
}
} = require('./package.json');
defaults.__set__('configFactory', (webpackEnv) => {
const config = webpackConfig(webpackEnv);
config.externals = externals;
return config;
});
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
...
<title>Atlas Reviews</title>
<script src="https://cdn.jsdelivr.net/npm/react#18.1.0/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom#18.1.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/#emotion/react#11.9.0/dist/emotion-react.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/#emotion/styled#11.8.1/dist/emotion-styled.umd.min.js"></script>
</head>
<body>
...
</body>
</html>
The problem I am getting is that #emotion/react and #emotion/styled aren't being externalized correctly.
Uncaught ReferenceError: emotion is not defined
at Object.#emotion/react (external var "emotion":1:1)
at Object.options.factory (react refresh:6:1)
at __webpack_require__ (bootstrap:24:1)
at fn (hot module replacement:62:1)
at Module../src/components/App/styles.tsx (index.tsx:25:1)
at Module.options.factory (react refresh:6:1)
at __webpack_require__ (bootstrap:24:1)
at fn (hot module replacement:62:1)
at Module../src/components/App/index.tsx (logo.svg:34:1)
at Module.options.factory (react refresh:6:1)
How do I fix this?
I managed to solve this, not with #emotion/react and #emotion/styled, but with styled-components.
To be fair, that was my initial preference for a CSS-in-JS framework.
In my previous attempts, I had been using the wrong version of the styled-components library.
Here's how I managed to do it:
package.json in all 4 React apps should be modified like so.
{
...
"dependencies": {
...
"#types/styled-components": "^5.1.25",
"rewire": "^6.0.0",
"styled-components": "^5.3.5",
...
},
"scripts": {
"start": "PORT=3004 node start.js",
"build": "PORT=3004 node build.js",
"test": "PORT=3004 react-scripts test",
"eject": "PORT=3004 react-scripts eject"
},
"webpackConfig": {
"externals": {
"react": "React",
"react-dom": "ReactDOM",
"react-is": "ReactIS",
"styled-components": "styled"
}
},
...
}
public/index.html in the 3 sub-frontends should be modified like so:
<!DOCTYPE html>
<html lang="en">
<head>
...
<title>Atlas Reviews</title>
<script src="https://cdn.jsdelivr.net/npm/react#18.1.0/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom#18.1.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-is#18.1.0/umd/react-is.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/styled-components#5.3.5/dist/styled-components.min.js"></script>
...
</head>
<body>
...
</body>
</html>
The public/index.html for the super-frontend will be similar, but will also include script tags to import the sub-frontends:
<!DOCTYPE html>
<html lang="en">
<head>
...
<title>Atlas Reviews</title>
<script src="https://cdn.jsdelivr.net/npm/react#18.1.0/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom#18.1.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-is#18.1.0/umd/react-is.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/styled-components#5.3.5/dist/styled-components.min.js"></script>
<script src="http://localhost:3001/static/js/bundle.js"></script>
<script src="http://localhost:3002/static/js/bundle.js"></script>
<script src="http://localhost:3003/static/js/bundle.js"></script>
...
</head>
<body>
...
</body>
</html>
TL;DR;: Note the externals for react-is and styled-components and the version of the styled-components script being loaded via CDN.

How to attach react code to html properly? (I get "Target container is not a DOM element" error)

I'm trying to setup a react web app with webpack 4, but I can't make it working, I get "Uncaught Invariant Violation: Target container is not a DOM element." console error.
I spent last 2 days trying everything and I've read all similar problems here in stackoverflow but nothing worked for me.
It should be a stupid bug (a typo or bad config) but I can't see it, for some reason it can't find my html file or div element with 'app' id.
My project structure:
This is the generated html by html webpack plugin:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<div id='app'></div>
<script type="text/javascript" src="bundle.js"></script>
</body>
</html>
My html template:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<div id='app'></div>
</body>
</html>
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('app')
);
App.js:
import React from 'react';
const App = () => {
return (
<div>
{'foobar'}
</div>
);
};
export default App;
webpack config:
const path = require('path');
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
path: path.join(__dirname, './dist'),
filename: 'bundle.js'
},
devServer: {
contentBase: './dist'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
plugins: [
new HtmlWebPackPlugin({
template: `./src/index.html`,
filename: `index.html`
})
]
};
I copied the code you provided with the same file structure (not including the jest and eslint files) you had and it successfully ran. Therefore, it's probably the inconsistencies in your webpack or babel versions that's causing the bug. Maybe you can try looking at my package.json compared to yours. Hope this helps!
package.json
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --mode development"
},
"author": "",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.4.3",
"#babel/preset-env": "^7.4.3",
"#babel/preset-react": "^7.0.0",
"babel": "^6.23.0",
"babel-loader": "^8.0.5",
"html-webpack-plugin": "^3.2.0",
"http-server": "^0.11.1",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.3.1"
},
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6"
}
}
.babelrc
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
I found the solution.
I was importing a component from one of my ui projects in App.js, I removed it an now is working fine.

html-webpack-plugin Entrypoint undefined = index.html

I'm trying to set a webpack4 and React boilerplate, but facing issue rendering the index.html. For example, when I updated the title of the index.html and the index.html in /dist folder is not updated, and only title is rendered while nothing in index.js is rendered. Please help take a look with below details in my project.
package.json
{
"name": "react-webpack-boilerplate",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.11",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"redux-immutable-state-invariant": "1.2.3",
"style-loader": "^0.21.0",
"webpack": "^4.6.0",
"webpack-cli": "^2.0.15",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"bootstrap": "^4.1.1",
"react": "^16.3.2",
"react-bootstrap": "^0.32.1",
"react-dom": "^16.3.2",
"react-redux": "^5.0.7",
"react-router": "2.4.0",
"react-router-redux": "4.0.4",
"redux": "3.5.2",
"redux-thunk": "2.0.1"
}
}
webpack.config.js:
// state rules for babel loader
// This plugin will generate html files with scripts injected
const HtmlWebPackPlugin = require("html-webpack-plugin");
const htmlPlugin = new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
});
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader" // it will look for .babelrc
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
},
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
localIdentName: "[name]_[local]_[hash:base64]",
sourceMap: true,
minimize: true
}
}
]
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000
}
}
}
]
},
plugins: [htmlPlugin]
};
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>React 2</title>
</head>
<body>
<section id="index"></section>
</body>
</html>
index.js:
import React from "react";
import {ReactDOM} from 'react-dom';
console.log('loading index js');
const App = () => {
return (
<div>
<h3>Our Application Is Alive</h3>
<p>This isn’t reality. This — is fantasy.</p>
<p>Yes I am quoting Star Trek I cant help it.</p>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('index'));
After build, the ./dist/index.html is not updated, see content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>React and Webpack4</title>
</head>
<body>
<section id="index"></section>
<script type="text/javascript" src="main.js"></script></body>
</html>
below are found in compilation message:
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
[./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html]
327 bytes {0} [built]
The webpack config needs to have an entry and optional output (req for multiple entries). It doesn't know which entries need to be added to index.html.
As as example in the docs:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: 'index.js',
output: {
path: __dirname + '/dist'
}
}
It will add the index.js to your index.html file.
As i just reported here https://github.com/jantimon/html-webpack-plugin/issues/1259
the property syntax is "fileName" and not "filename"
This is a meaningless error in webpack 4, runing with an earlier version of webpack like 3.0.7 or ignoring the error with stats: {
children: false,
}
will fix this https://github.com/jantimon/html-webpack-plugin/issues/895

How to configure service workers with create-react-app

I am creating a ReactJS app with the create-react-app utility. How could I configure it to use a file that will contain a service worker?
EDIT:
From Javascript side is clear for me, add the registration in my index.js:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./service_workers/sw.js')
.then(function(registration) {
// Registration was successful...
}).catch(function(err) {
// registration failed ...
});
}
Then my configuration in my service worker file (that for me is in service_wokers/sw.js):
self.addEventListener('install', function(event) {//my code here...});
self.addEventListener('activate', function(event) {//my code here...});
self.addEventListener('fetch', function(event) {//my code here...});
When I run this the console shows:
ServiceWorker registration failed: DOMException: Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script.
The file is not there as I am not configuring Webpack to do that. So I am trying to copy the sw.js file with the ouput with:
test:
/\.(js)$/,
loader: "file?name=[path][name].[ext]&context=./service_workers",
include: '/service_worker'
I think there is no need to say that I am totally new to Webpack.
for people who are still struggling on this. please refer https://create-react-app.dev/docs/making-a-progressive-web-app.
service workers are configured in CRA and will handle the caching for you! You just need to change :-
serviceWorker.unregister();
to
serviceWorker.register();
in your src/index.js file;
Also, service workers work on production mode only so make sure to build your application and serve it locally before testing your app for service workers.
npm i http-server -D
then add this to package.json, in your scripts.
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"start-sw": "http-server ./build"
}
now run :-
npm run build && npm run start-sw
hope it helps!
First, you have to do some changes in package.json:
Changes in package.json:
{
"name": "create-react-pwa",
"version": "0.1.0",
"private": true,
"devDependencies": {
"react-scripts": "0.7.0",
"sw-precache": "^4.2.2"
},
"dependencies": {
"react": "^15.4.0",
"react-dom": "^15.4.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build && sw-precache --config=sw-precache-config.js",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
Then create a js file "sw-precache-confi.js" in the root folder of your project:
sw-precache-config.js:
module.exports = {
stripPrefix: 'build/',
staticFileGlobs: [
'build/*.html',
'build/manifest.json',
'build/static/**/!(*map*)'
],
dontCacheBustUrlsMatching: /\.\w{8}\./,
swFilePath: 'build/service-worker.js'
};
Changes in index.html, Add service worker in index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<!--
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 "favicon.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>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
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`.
To create a production bundle, use `npm run build`.
-->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}
</script>
</body>
</html>
After doing all the things run npm install at root of project then npm start.
Further reading: https://github.com/jeffposnick/create-react-pwa#what-additional-changes-might-be-needed
I would recommend this library called cra-append-sw to add custom service workers to CRA.
Most of the details of how to use it are in the npm page, but simply put you just need to install the library (npm i --save cra-append-sw).
Make a few changes to your package.json:
"start": "react-scripts start && cra-append-sw --mode dev ./public/custom-sw-import.js",
"build": "react-scripts build && cra-append-sw --skip-compile ./public/custom-sw-import.js"
And finally create a file in your public folder called custom-sw-import.js and all of the service worker code you write there will simply be appended to cra's service worker.
I can verify this works since I applied the same principle to make my website www.futurist-invenzium.com which gives a demo of all the features provided by PWA's.
I also found this blogpost to be helpful if you want a more indepth answer : https://medium.freecodecamp.org/how-to-build-a-pwa-with-create-react-app-and-custom-service-workers-376bd1fdc6d3
Service workers and offline functionality should be included now in create-react-app builds, see this pr

Resources