If I generate production js bundle in my next.js project, it's not minified.
For example white characters are not removed.
package.json
{
"name": "web",
"version": "0.1.0",
"private": true,
"scripts": {
"web": "cross-env NODE_ENV=development node server.js",
"dev": "next",
"devServer": "node server.js",
"build": "next build",
"start": "next start"
},
"dependencies": {
"#zeit/next-css": "^1.0.1",
"apollo-boost": "^0.4.4",
"apollo-upload-client": "^11.0.0",
"body-parser": "^1.19.0",
"cross-env": "^6.0.3",
"express": "^4.17.1",
"graphql": "^14.5.8",
"intl": "^1.2.5",
"js-cookie": "^2.2.1",
"js-cookies": "^1.0.4",
"lodash.chunk": "^4.2.0",
"next": "9.1.2",
"next-cookies": "^2.0.3",
"next-with-apollo": "^4.3.0",
"optimize-css-assets-webpack-plugin": "^6.0.0",
"react": "16.11.0",
"react-apollo": "^3.1.3",
"react-dom": "16.11.0",
"react-image-lightbox": "^5.1.1",
"react-input-range": "^1.3.0",
"react-intl": "^3.6.1",
"react-modal": "^3.11.1",
"react-perfect-scrollbar": "^1.5.3",
"react-slick": "^0.25.2",
"slick-carousel": "^1.8.1"
},
"devDependencies": {
"babel-eslint": "^10.1.0",
"eslint": "^7.25.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.2",
"eslint-plugin-react-hooks": "^4.2.0"
}
}
next.config.js
const withCSS = require("#zeit/next-css");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = withCSS({
webpack(config, options) {
config.optimization.minimizer = [];
config.optimization.minimizer.push(new OptimizeCSSAssetsPlugin({}));
return config;
},
distDir: "build",
});
server.js
const express = require('express');
const next = require('next');
const bodyParser = require("body-parser");
const dev = process.env.NODE_ENV !== undefined;
var app;
if(dev){
app = next({ dev});
}else{
app = next({ dev,conf:{
distDir: 'build'
} });
}
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
server.use('/Public', express.static(__dirname + '/Public'));
server.use('/.well-known', express.static(__dirname + '/Public'));
server.use(bodyParser.urlencoded({ extended: false }));
server.use(bodyParser.json());
server.get('/', (req, res) => {
return app.render(req, res, '/index');
});
server.get('/robots.txt', (req, res) => {
return app.render(req, res, '/robots');
});
server.get('/sitemap.xml', (req, res) => {
return app.render(req, res, '/sitemap');
});
server.listen(8890, err => {
if (err) throw err
console.log('> Ready on http://localhost:8890')
})
})
If I run npm run build, dev variable in server.js is false.
The issue is on line:
config.optimization.minimizer = [];
Removing this line, minification works.
Related
I have created a next.js app in there I have a custom server dir. I am using koa.js as my custom server. It works fine on development but, when I build the app, the api routes show 404 not found error. Below is my package.json
{
"name": "dogs",
"version": "0.1.0",
"private": true,
"engines": {
"node": ">=18.7.0",
"yarn": ">=1.22.17",
"npm": "please-use-yarn"
},
"scripts": {
"dev": "nodemon ./server/index.js",
"ngrok": "ngrok http 3000",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prettier": "prettier --write .",
"prepare": "husky install",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"dependencies": {
"#babel/polyfill": "^7.12.1",
"#babel/preset-env": "^7.20.2",
"#babel/register": "^7.18.9",
"#fireworks-js/preact": "^2.10.1",
"#koa/cors": "^4.0.0",
"#next/font": "13.1.1",
"#react-email/button": "^0.0.6",
"#react-email/container": "^0.0.7-canary.1",
"#react-email/head": "^0.0.4",
"#react-email/hr": "^0.0.4",
"#react-email/html": "^0.0.4",
"#react-email/img": "^0.0.4",
"#react-email/link": "^0.0.4",
"#react-email/preview": "^0.0.5",
"#react-email/render": "^0.0.6",
"#react-email/section": "^0.0.7-canary.1",
"#react-email/text": "^0.0.4",
"#sendgrid/mail": "^7.7.0",
"TagCloud": "^2.3.2",
"autoprefixer": "^10.4.13",
"aws-sdk": "^2.1300.0",
"babel-polyfill": "^6.26.0",
"bcryptjs": "^2.4.3",
"daisyui": "^2.47.0",
"dotenv": "^16.0.3",
"eslint": "8.30.0",
"eslint-config-next": "13.1.1",
"express": "^4.18.2",
"framer-motion": "^9.0.1",
"gsap": "^3.11.4",
"isomorphic-fetch": "^3.0.0",
"jsonwebtoken": "^9.0.0",
"koa": "^2.14.1",
"koa-body": "^6.0.1",
"koa-cache-control": "^2.0.0",
"koa-combine-routers": "^4.0.2",
"koa-conditional-get": "^3.0.0",
"koa-cookie": "^1.0.0",
"koa-etag": "^4.0.0",
"koa-mongo": "^1.9.3",
"koa-multer": "^1.0.2",
"koa-router": "^12.0.0",
"koa-session": "^6.2.0",
"koa-static": "^5.0.0",
"koa-static-cache": "^5.1.4",
"mongodb": "^4.13.0",
"mongoose": "^6.8.2",
"multer": "^1.4.5-lts.1",
"next": "13.1.1",
"postcss": "^8.4.20",
"primereact": "^8.7.3",
"react": "18.2.0",
"react-confetti": "^6.1.0",
"react-dom": "18.2.0",
"react-icons": "^4.7.1",
"react-multi-select-component": "^4.3.4",
"react-particles": "^2.8.0",
"react-select": "^5.7.0",
"react-tsparticles": "^2.8.0",
"split-type": "^0.3.3",
"tailwindcss": "^3.2.4",
"tsparticles": "^2.8.0",
"tsparticles-engine": "^2.8.0",
"tsparticles-preset-fireworks": "^2.8.0",
"winston": "^3.8.2"
},
"devDependencies": {
"#babel/core": "^7.20.7",
"#commitlint/cli": "^17.3.0",
"#commitlint/config-conventional": "^17.3.0",
"#storybook/addon-actions": "^6.5.15",
"#storybook/addon-essentials": "^6.5.15",
"#storybook/addon-interactions": "^6.5.15",
"#storybook/addon-links": "^6.5.15",
"#storybook/builder-webpack5": "^6.5.15",
"#storybook/manager-webpack5": "^6.5.15",
"#storybook/react": "^6.5.15",
"#storybook/testing-library": "^0.0.13",
"babel-loader": "^8.3.0",
"cross-env": "^7.0.3",
"husky": "^8.0.2",
"ngrok": "^4.3.3",
"nodemon": "^2.0.20",
"prettier": "^2.8.1"
},
"resolutions": {
"webpack": "^5"
}
}
Below is my server code
import '#babel/polyfill';
import dotenv from 'dotenv';
import 'isomorphic-fetch';
import next from 'next';
import Koa from 'koa';
import Router from 'koa-router';
import UserRouter from './routes/user';
import DataRouter from './routes/data';
import EmailRouter from './routes/emails';
import MongoClientConnection from './db';
import cookie from 'koa-cookie';
dotenv.config();
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const server = new Koa();
const router = new Router();
// Initialize NextJs instance and expose request handler
const app = next({ dev });
const handler = app.getRequestHandler();
(async () => {
try {
await app.prepare();
router.get('/custom-page', async (ctx) => {
await app.render(ctx.req, ctx.res, '/', ctx.query);
ctx.respond = false;
});
const db = await MongoClientConnection.Get();
server.context.db = db;
const handleRequest = async (ctx) => {
await handler(ctx.req, ctx.res);
ctx.respond = false;
ctx.res.statusCode = 200;
};
router.get('/_next/webpack-hmr', handleRequest); // Webpack content is clear
router.get('(.*)', async (ctx) => {
await handleRequest(ctx);
});
server.use(cookie());
server.use(UserRouter.routes()).use(UserRouter.allowedMethods());
server.use(DataRouter.routes()).use(DataRouter.allowedMethods());
server.use(EmailRouter.routes()).use(EmailRouter.allowedMethods());
server.use(router.routes());
server.listen(port, (_) => console.log(`App running on port ${port}`));
} catch (e) {
console.error(e);
process.exit();
}
})();
How can I build my next.js app so my api routes work on production?
I'm using micro-frontend in nextjs.
Wen i start the server, in the next.config.js am getting
TypeError: withModuleFederation is not a function
I tried the latest version of #module-federation/nextjs-mf but in this I'm getting version mismatch error.
any suggestion or solution ??
next.config.js content
const {
withModuleFederation,
MergeRuntime,
} = require("#module-federation/nextjs-mf");
const path = require("path");
module.exports = {
webpack: (config, options) => {
const { buildId, dev, isServer, defaultLoaders, webpack } = options;
const mfConf = {
name: "test1",
library: { type: config.output.libraryTarget, name: "test1" },
filename: "static/runtime/remoteEntry.js",
remotes: {},
exposes: {
"./nav": "./components/nav",
},
shared: [],
};
withModuleFederation(config, options, mfConf);
config.plugins.push(new MergeRuntime());
if (!isServer) {
config.output.publicPath = "http://localhost:3000/_next/";
}
return config;
},
};
package.json content
{
"name": "charts",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"resolutions": {
"webpack": "5.1.3"
},
"dependencies": {
"#module-federation/nextjs-mf": "^2.3.1",
"next": "12.1.6",
"react": "18.1.0",
"react-dom": "18.1.0"
},
"devDependencies": {
"#types/node": "^17.0.40",
"#types/react": "^18.0.12",
"eslint": "8.17.0",
"eslint-config-next": "12.1.6",
"typescript": "^4.7.3"
}
}
#module-federation/nextjs-mf is no longer free, if its required need to purchase from
module-federation/nextjs-mf
I am getting the error Parsing error: Unexpected token => when I try to deploy my Vue JS application to firebase. The application runs fine on my local machine but I am not able to deploy to firebase.
Here is the full error
=== Deploying to 'mmmmnl-d5ddc'...
i deploying storage, firestore, functions, hosting
Running command: npm --prefix "$RESOURCE_DIR" run lint
> lint
> eslint .
/Users/KingdomMac/Downloads/ermnl_delivery/ermnl-dashboard/functions/index.js
22:71 error Parsing error: Unexpected token =>
✖ 1 problem (1 error, 0 warnings)
Error: functions predeploy error: Command terminated with non-zero exit code1
I have added ecmaVersion: 8 to parserOptions. I have changed it to 6, I have also changed it to 2017 as suggested by some other answers.
Here is my .eslintrc.js file
module.exports = {
root: true,
env: {
node: true
},
extends: ["plugin:vue/essential", "#vue/prettier"],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
},
parserOptions: {
parser: 'babel-eslint',
ecmaVersion: 2017
},
'extends': [
'plugin:vue/essential',
'#vue/prettier',
'#vue/standard'
]
};
Here is my package.json file
{
"name": "vue-white-dashboard",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^1.2.35",
"#fortawesome/free-brands-svg-icons": "^5.15.3",
"#fortawesome/free-regular-svg-icons": "^5.15.3",
"#fortawesome/free-solid-svg-icons": "^5.15.3",
"#fortawesome/vue-fontawesome": "^2.0.2",
"axios": "^0.21.1",
"chart.js": "^2.8.0",
"core-js": "^2.6.5",
"firebase": "^8.6.8",
"node-sass": "^6.0.1",
"vue": "^2.6.10",
"vue-chartjs": "^3.4.2",
"vue-click-outside": "^1.0.7",
"vue-clickaway": "^2.2.2",
"vue-github-buttons": "^3.1.0",
"vue-i18n": "^8.14.1",
"vue-router": "^3.0.3",
"vue-social-sharing": "^2.4.6",
"vue2-transitions": "^0.3.0",
"vuetify": "^2.4.0"
},
"devDependencies": {
"#vue/cli-plugin-babel": "^3.3.0",
"#vue/cli-plugin-eslint": "^3.1.1",
"#vue/cli-service": "^4.5.15",
"#vue/eslint-config-prettier": "^5.0.0",
"#vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"eslint": "^8.2.0",
"eslint-config-eslint": "^7.0.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^7.14.0",
"prettier": "^1.18.2",
"sass": "~1.32",
"sass-loader": "^10.0.0",
"vue-cli-plugin-vuetify": "~2.4.1",
"vue-template-compiler": "^2.6.10",
"vuetify-loader": "^1.7.0"
}
}
None of the the other resources I have read points out the problem to be from their code. But I am just adding functions/index.js here incase the problem is from the that file.
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
exports.addUserRole = functions.auth.user().onCreate(async (authUser) => {
if (authUser.email) {
const customClaims = {
admin: true,
};
try {
let _ = await admin.auth().setCustomUserClaims(authUser.uid, customClaims);
return db.collection("roles").doc(authUser.uid).set({
email: authUser.email,
role: customClaims,
});
} catch (error) {
console.log(error);
}
}
});
exports.setUserRole = functions.https.onCall(async (data, context) => {
if (!context.auth.token.admin) return
try {
let _ = await admin.auth().setCustomUserClaims(data.uid, data.role)
return db.collection("roles").doc(data.uid).update({
role: data.role
})
} catch (error) {
console.log(error)
}
});
As requested in the comments, I have added my firebase.json
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
],
"source": "functions"
},
"storage": {
"rules": "storage.rules"
},
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
I have a react-redux app that I have initiated from create-react-app. From my understanding, what is needed to run jest is already configured for you in create-react-app(i.e. webpack files, babel, etc).
So I have create a test suite called CreateQueryActions.test.js and this files contains one test suite with all necessary components (to the best of my knowledge) - describe/it/expect.
When I run npm run test jest sees the file but it fails with Test suite failed to run Your test suite must contain at least one test.
but it does have a test. So whats happening here?
import { tableList } from "../../utils/CreateQueryMockData";
import * as createQueryActions from "./CreateQueryActions";
import thunk from "redux-thunk";
import fetchMock from "fetch-mock";
import configureMockStore from 'redux-mock-store';
//Async test dependencies
const middleware = [thunk];
const mockStore = configureMockStore(middleware);
describe("create query API calls", () => {
afterEach(() => {
/*Its importatnt to keep this test atomic.
* This initialized fetchMock for each test -
* needs to be reset after each test has ran
* */
fetchMock.restore();
});
it("should create a 'GET_TABLE_LIST' action", () => {
fetchMock.mock("*", {
body: tableList,
headers: { "content-type": "application/json" }
});
const expectedAction = [
{ type: "GET_TABLE_LIST" }
];
const store = mockStore({ tableList: [] });
return store.dispatch(createQueryActions.getTableList()).then(() => {
expect(store.getActions()).toEqual(expectedAction);
});
});
});
PACKAGE.JSON
{
"name": "queryapp",
"version": "1.0.0",
"private": true,
"dependencies": {
"axios": "^0.19.0",
"bootstrap": "^4.3.1",
"history": "^4.9.0",
"http-proxy-middleware": "^0.19.1",
"jest": "^24.7.1",
"oidc-client": "^1.8.2",
"react": "^16.8.6",
"react-bootstrap": "^1.0.0-beta.5",
"react-csv": "^1.1.1",
"react-dom": "^16.8.6",
"react-redux": "^5.1.1",
"react-router-dom": "^5.0.1",
"react-scripts": "3.0.1",
"react-table": "^6.10.0",
"redux": "^4.0.4",
"redux-form": "^7.4.2",
"redux-form-validators": "^2.7.5",
"redux-oidc": "^3.1.2",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"fetch-mock": "^7.3.9",
"redux-immutable-state-invariant": "^2.1.0",
"redux-logger": "^3.0.6",
"redux-mock-store": "^1.5.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
afterEach is not a test case. It is used to perform some task after each test case. Your test case should be like below:
describe("create query API calls", () => {
it("should create a 'GET_TABLE_LIST' action", () => {
fetchMock.mock("*", {
body: tableList,
headers: { "content-type": "application/json" }
});
const expectedAction = [
{ type: "GET_TABLE_LIST" }
];
const store = mockStore({ tableList: [] });
return store.dispatch(createQueryActions.getTableList()).then(() => {
expect(store.getActions()).toEqual(expectedAction);
});
});
Using the same credentials the login login action hangs at firebase.auth() when chrome debug is on. It hangs until I tap on the screen. Only then the login proceeds.
As soon as I turn chrome debug off, the login action incl. firebase.auth() runs as fast as expected.
here is my package.json an the affected action:
Action:
export const loginUser = ({ email, password }) => (dispatch) => {
dispatch({ type: LOGIN_USER });
return firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((user) => {
setTimeout(() => null, 0);
dispatch(() => saveCredentials(email, password))
.then(dispatch(loginUserSuccess(user)))
.then(dispatch(weekplanFetch()))
.then(dispatch(recipeLibraryFetch()))
.then(() => {
NavigationService.navigate('Home');
});
})
.catch((error) => {
console.log(`sign in fail ${error}`);
return firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((user) => {
dispatch(() => saveCredentials(email, password))
.then(dispatch(loginUserSuccess(user)))
.then(dispatch(initWeekplan()))
.then(dispatch(initRecipeLibrary()))
.then(() => {
NavigationService.navigate('Home');
});
})
.catch((userCreateFail) => {
// console.log(`user create fail ${userCreateFail}`);
dispatch(loginUserFail(userCreateFail.message));
});
});
};
package.json
{
"name": "WhatsForDinner",
"version": "1.0.5",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest",
"ios:beta": "(cd ios/ && bundle exec fastlane beta)",
"ios:commit": "cd ios/ && bundle exec fastlane commit",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prettier": "prettier --write '*.js'",
"format-code": "yarn run prettier && yarn run lint:fix",
"precommit": "lint-staged",
"test:coverage": "jest --coverage && open coverage/lcov-report/index.html"
},
"lint-staged": {
"*.js": [
"yarn run format-code",
"git add",
"jest --bail --findRelatedTests --coverage"
]
},
"dependencies": {
"firebase": "^5.8.6",
"prop-types": "^15.6.0",
"react": "16.6.3",
"react-native": "0.57.8",
"react-native-code-push": "^5.5.2",
"react-native-image-picker": "^0.28.0",
"react-native-keychain": "^3.0.0",
"react-native-paper": "^1.12.0",
"react-native-vector-icons": "^6.4.1",
"react-navigation": "^1.6.1",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"yarn": "^1.9.4"
},
"devDependencies": {
"babel-eslint": "^8.2.2",
"babel-jest": "^23.4.2",
"babel-preset-react-native": "^5",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.6.0",
"eslint": "^4.18.1",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.12.3",
"husky": "^0.14.3",
"jest": "22.4.2",
"jest-fetch-mock": "^2.1.0",
"lint-staged": "^7.2.2",
"prettier": "1.10.2",
"react-dom": "^16.7.0",
"react-test-renderer": "16.4.1",
"redux-mock-store": "^1.5.3"
},
"jest": {
"preset": "react-native",
"setupFiles": [
"<rootDir>/tests/setup.js"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
},
"collectCoverageFrom": [
"app/**/*.js",
"!app/components/index.js"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-navigation)"
]
}
}