EDIT: Updated the text in general to keep it shorter and more concise.
I am trying to configure HTTPS when I run npm run dev so I can test MediaStream and alike locally (for which browsers require me to provide HTTPS).
I am trying to configure it through nuxt.config.js but without any success.
Here is my nuxt.config.js file:
import fs from "fs";
import pkg from "./package";
export default {
mode: "spa",
/*
** Headers of the page
*/
head: {
title: pkg.name,
meta: [
{ charset: "utf-8" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },
{ hid: "description", name: "description", content: pkg.description },
],
link: [
{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
],
},
/*
** Customize the progress-bar color
*/
loading: { color: "#fff" },
/*
** Global CSS
*/
css: [
"element-ui/lib/theme-chalk/index.css",
"#makay/flexbox/flexbox.min.css",
],
/*
** Plugins to load before mounting the App
*/
plugins: [
"#/plugins/element-ui",
"#/plugins/vue-upload",
"#/plugins/axios-error-event-emitter",
"#/plugins/eventemitter2",
"#/plugins/vue-awesome",
"#/plugins/webrtc-adapter",
"#/plugins/vue-browser-detect-plugin",
],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://axios.nuxtjs.org/usage
"#nuxtjs/axios",
"#nuxtjs/pwa",
],
/*
** Axios module configuration
*/
axios: {
// See https://github.com/nuxt-community/axios-module#options
baseURL: process.env.NODE_ENV === "production" ? "https://startupsportugal.com/api/v1" : "http://localhost:8080/v1",
},
/*
** Build configuration
*/
build: {
transpile: [/^element-ui/, /^vue-awesome/],
filenames: {
app: ({ isDev }) => (isDev ? "[name].[hash].js" : "[chunkhash].js"),
chunk: ({ isDev }) => (isDev ? "[name].[hash].js" : "[chunkhash].js"),
},
/*
** You can extend webpack config here
*/
extend(config, ctx) {
// Run ESLint on save
if (ctx.isClient) config.devtool = "#source-map";
if (ctx.isDev) {
config.devServer = {
https: {
key: fs.readFileSync("server.key"),
cert: fs.readFileSync("server.crt"),
ca: fs.readFileSync("ca.pem"),
},
};
}
if (ctx.isDev && ctx.isClient) {
config.module.rules.push({
enforce: "pre",
test: /\.(js|vue)$/,
loader: "eslint-loader",
exclude: /(node_modules)/,
});
}
},
},
};
Also, here you can see my dependencies in package.json:
"dependencies": {
"#makay/flexbox": "^3.0.0",
"#nuxtjs/axios": "^5.3.6",
"#nuxtjs/pwa": "^2.6.0",
"cross-env": "^5.2.0",
"element-ui": "^2.4.11",
"eventemitter2": "^5.0.1",
"lodash": "^4.17.11",
"nuxt": "^2.8.0",
"pug": "^2.0.3",
"pug-plain-loader": "^1.0.0",
"quagga": "^0.12.1",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"vue-awesome": "^3.5.3",
"vue-browser-detect-plugin": "^0.1.2",
"vue-upload-component": "^2.8.20",
"webrtc-adapter": "^7.2.4"
},
"devDependencies": {
"#nuxtjs/eslint-config": "^0.0.1",
"babel-eslint": "^10.0.1",
"eslint": "^5.15.1",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-config-standard": ">=12.0.0",
"eslint-import-resolver-webpack": "^0.11.1",
"eslint-loader": "^2.1.2",
"eslint-plugin-import": ">=2.16.0",
"eslint-plugin-jest": ">=22.3.0",
"eslint-plugin-node": ">=8.0.1",
"eslint-plugin-nuxt": ">=0.4.2",
"eslint-plugin-promise": ">=4.0.1",
"eslint-plugin-standard": ">=4.0.0",
"eslint-plugin-vue": "^5.2.2",
"nodemon": "^1.18.9"
}
However when I run npm run dev it still does not provide HTTPS, but does not provide any error output as well...
The output is exactly the same as if I didn't have the HTTPS configurations in nuxt.config.js:
$ npm run dev
> clothing-demo#1.0.0 dev /mnt/d/tralha/clothing-demo-app/frontend
> nuxt --hostname 0.0.0.0 --port 3000
╭────────────────────────────────────────────────╮
│ │
│ Nuxt.js v2.8.1 │
│ Running in development mode (spa) │
│ │
│ Listening on: http://192.168.126.241:3000/ │
│ │
╰────────────────────────────────────────────────╯
ℹ Preparing project for development 14:30:34
ℹ Initial build may take a while 14:30:35
✔ Builder initialized 14:30:35
✔ Nuxt files generated
HTTPS on local dev - NUXT style
Solution is described in NUXT documentation:
https://nuxtjs.org/api/configuration-server/#example-using-https-configuration
This may be achieved with:
Go to project main dir;
Create private and public key;
openssl genrsa 2048 > server.key
chmod 400 server.key
openssl req -new -x509 -nodes -sha256 -days 365 -key server.key -out server.crt
Add requirements to the top of the nuxt.config.js;
import path from 'path'
import fs from 'fs'
Extend or add configuration of server in nuxt.config.js;
server: {
https: {
key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
}
}
You must follow the doc spec here https://nuxtjs.org/api/configuration-server/#example-using-https-configuration, BUT you must add code in the server/index.js file, otherwise it won’t work at all.
So in the server/index.js add const https = require('https') at the top and replace :
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
})
With
https.createServer(nuxt.options.server.https, app).listen(port, host);
And now it’s working!
You can use mkcert
Install mkcert:
brew install mkcert
brew install nss # if you use Firefox
Add mkcert to your local root CAs:
mkcert -install
In your terminal, navigate to your site's root directory or whichever directory you'd like the certificates to be located at. And run:
mkcert localhost
Add the following to your nuxt.config.js:
server: {
https: {
key: fs.readFileSync(path.resolve(__dirname, 'localhost-key.pem')),
cert: fs.readFileSync(path.resolve(__dirname, 'localhost.pem'))
}
}
https://web.dev/how-to-use-local-https/
If for some reason you enable https just like Jan Doleczek said and you also make use of axios module, make sure to disable https like this in nuxt.config.js:
axios: {
baseURL: 'http://yourapi:8000',
https:false,
},
If you don't do that all your axios request will use https instead of https.
Nuxt 3:
options.server from nuxt.config is not supported. You can use --port, --host, --https, --ssl-cert and --ssl-key instead.
official docs
Something like this:
{
"scripts": {
"dev": "nuxi dev --host website.test --https --ssl-key key.pem --ssl-cert cert.pem --port 3000",
}
I hope I didn't lose -- in example :-)
In the scenario to run local on https and share a domain or subdomain to share secured cookies for Single Sign On etc follow the below
Prerequisites
openssl
if you're on Windows you can find openssl.exe in C:\Program Files\Git\usr\bin
your .pfx certificate
including password if required
1. Create .crt and .key files using openssl.exe
1.1 Create key
pkcs12 -in '[full-path-and-name-of-your].pfx' -nocerts -out '[full-path-and-name-to-create-the].key'
if prompted enter the password to open your .pfx
1.2 Create crt
pkcs12 -in '[full-path-and-name-of-your].pfx' -clcerts -nokeys -out '[full-path-and-name-to-create-the].crt'
Move the .key and .crt to the root of your source folder
See more details here
2. Update server config likely in nuxt.config.js
As other answers suggested follow the changes to set up https from Nuxt documentation
Enter the password used to at step 1 as the passphase value
server: {
https: {
key: fs.readFileSync(path.resolve(__dirname, '[key-file-name].key')),
cert: fs.readFileSync(path.resolve(__dirname, '[crt-file-name].crt')),
passphrase: '[your password]'
}
}
3. Create / Modify local build script to specify hostname
"dev": "nuxt --hostname subdmain.domain.com --port 8000"
Your local will now serve on https on that domain/subdomain and port e.g. https://subdmain.domain.com:8000
Related
I've switched from Laravel Mix to Vite, and am trying to accomplish same thing "npm run watch" does for Laravel Mix. Caveat: our staging servers are not local (i.e. staging.app-domain-name.com). If I run npm run dev with Vite it revs up the "dev" server that's supposed to be at http://ip:3000, but that obviously does not work. Aside from not having an active watcher, I can't get the dev to be used with Vue Devtools plugin (since vite only can spit out prod on server).
My vite.config.js:
const { resolve } = require('path');
import vue from '#vitejs/plugin-vue';
export default ({ command }) => ({
base: command === 'serve' ? '' : '/dist/',
publicDir: 'fake_dir_so_nothing_gets_copied',
build: {
manifest: true,
outDir: resolve(__dirname, 'public/dist'),
rollupOptions: {
input: 'resources/js/app.js',
},
},
server: {
host: true,
port: '8080',
hot: true
},
plugins: [vue()],
resolve: {
alias: {
'#': resolve('./resources/js'),
},
},
});
My app.js
import "./bootstrap";
import '../css/app.css';
import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
let asyncViews = () => {
return import.meta.glob('./Pages/**/*.vue');
}
const el = document.getElementById('app');
createApp({
render: () =>
h(InertiaApp, {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: async name => {
if (import.meta.env.DEV) {
return (await import(`./Pages/${name}.vue`)).default;
} else {
let pages = asyncViews();
const importPage = pages[`./Pages/${name}.vue`];
return importPage().then(module => module.default);
}
}
}),
})
.mixin({ methods: { route } })
.use(InertiaPlugin)
.mount(el);
And package.json scripts:
"scripts": {
"predev": "printf \"dev\" > public/hot",
"dev": "vite",
"preprod": "printf \"prod\" > public/hot",
"prod": "vite build"
}
Desired outcome to generate dev bundle on a remote server by running
npm run dev
Currently it tries to create localhost dev. I assume something in vite.config.js needs to be set to get that done. I've gone over the docs but could not find anything clear enough.
To tell Vite to listen also on network interface simply add --host parameter to dev script:
"scripts": {
"dev": "vite --host",
"prod": "vite build"
},
It gives me an result like this:
vite v2.5.10 dev server running at:
> Local: http://localhost:3000/
> Network: http://x.y.x.z:3000/ <-- server public IP
> Network: http://10.10.10.1:3000/ <-- server local IP via VPN
ready in 330ms.
But this was not solution. I had a problem with CORS. I resolved it in another way. It depends on web server. I use nGinx and I set reverse proxy to listen on port 3000.
server {
listen x.y.x.z:3000 ssl; ### Server public IP address
server_name dev.example.com;
location / {
proxy_pass https://127.0.0.1:3000/; ### https: is Important
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
# SSL config
ssl_certificate /srv/certs/example.com/fullchain.cer;
ssl_certificate_key /srv/certs/example.com/example.com.key;
include ssl_config;
}
Ii is also important to listen only on public IP address due to not conflict with vite on same port. Vite default listen only on localhost. Reload nGinx
sudo nginx -t
sudo systemctl reload nginx
In package.json I put --https atribute
{
"private": true,
"scripts": {
"dev": "vite --https",
"prod": "vite build"
},
"devDependencies": {
"postcss": "^8.1.14",
"vite": "^2.5.10"
}
}
And that's it. Now I am able run
npm run dev
Finnally I put scripts to my layout blade end Vite start works.
<script type="module" src="https://dev.example.com:3000/#vite/client"></script>
<script type="module" src="https://dev.example.com:3000/resources/js/app.js"></script>
Setup nginx to proxy websocket
https://www.nginx.com/blog/websocket-nginx/
Sebastyan's guide to setup Vite with Laravel
https://sebastiandedeyne.com/vite-with-laravel
Adding this server part of this config to my config in vite.config.js file fixed things for me.
export default defineConfig({
server: {
hmr: {
host: 'localhost',
}
}
});
Except you may want to change the host part from localhost to your server's IP address.
Then do npm run dev -- --host as others have mentioned.
I copy pasted this answer from here without reading anything else about it or why it works.
Adding --host separated by -- worked in my case - no changes in config files needed this way:
npm run dev -- --host
Try this:
CMD [ "npm", "run", "dev", "--", "--host"]
It worked for me but the app keeps reloading
Adding the arguments "--" "--host" to my Docker file did the trick.
like so:
CMD [ "npm", "run", "dev", "--", "--host"]
this allows me to start the server in dev mode and to reach it from my host.
{
"name": "zustand",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"cmd": "cmd /k npm run dev -- --host",
"host": "vite --host",
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"#tanstack/react-query": "^4.20.9",
"axios": "^1.2.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"zustand": "^4.2.0"
},
"devDependencies": {
"#types/react": "^18.0.26",
"#types/react-dom": "^18.0.10",
"#vitejs/plugin-react": "^3.0.1",
"typescript": "^4.9.4",
"vite": "^4.0.4"
}
}
---
vite --host
VITE v4.0.4 ready in 623 ms
➜ Local: http://localhost:5173/
➜ Network: http://172.19.80.1:5173/
➜ Network: http://192.168.100.14:5173/
➜ press h to show help
para que funcione "vite --host", debe estar instalado globalmente.
Ej: npm install vite -g
I'm using apollo-boost: ^0.4.3 with next.js. I recently added cookie authentication to my website. The biggest change was adding headers and credentials: 'include' to ApolloClient constructor. In addition in the server.js which starts express server for next.js I added this block:
const getServer = (isDevHttps, expressApp) => {
if (isDevHttps) {
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
const httpsServerOptions = {
key: fs.readFileSync(path.resolve('cert', 'localhost.key')),
cert: fs.readFileSync(path.resolve('cert', 'localhost.crt'))
};
console.info('creating https server');
return createServer(httpsServerOptions, expressApp);
}
return expressApp;
};
because I needed to run in https in development. Everything worked in development (I was using https://localhost:3000 for client and https://localhost:443 for the graphql backend server). However when I push ed my code to staging where nginx serves static files and AWS hosts the instance I started getting this error:
ApolloError: Network error: request to https://beta.leafreport.com/graphql/ failed, reason: write EPROTO 140426009438016:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1536:SSL alert number 40
at new ApolloError (/src/node_modules/apollo-client/bundle.umd.js:92:26)
at /src/node_modules/apollo-client/bundle.umd.js:1588:34
at /src/node_modules/apollo-client/bundle.umd.js:2008:15
at Set.forEach (<anonymous>)
at /src/node_modules/apollo-client/bundle.umd.js:2006:26
at Map.forEach (<anonymous>)
at QueryManager.broadcastQueries (/src/node_modules/apollo-client/bundle.umd.js:2004:20)
at /src/node_modules/apollo-client/bundle.umd.js:1483:29
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
graphQLErrors: [],
networkError: FetchError: request to https://staging.mysite.com/graphql/ failed, reason: write EPROTO 140426009438016:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1536:SSL alert number 40
The first time when I pushed the code isDevHttps was true by mistake and NODE_TLS_REJECT_UNAUTHORIZED was set to 0. Afterwards I made sure that isDevHttps is false and redeployed. The SSL certificate we use is provided by AWS Cloudfront.
This is the init code for Apollo Client:
import withApollo from 'next-with-apollo';
import ApolloClient, { InMemoryCache } from 'apollo-boost';
import { graphql_url } from 'my-config';
import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import introspectionQueryResultData from '../../fragmentTypes.json';
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData
});
function createClient({ ctx, headers, initialState }) {
return new ApolloClient({
credentials: 'include',
uri: graphql_url,
cache: new InMemoryCache({ fragmentMatcher }).restore(initialState || {}),
headers
});
}
export default withApollo(createClient, { getDataFromTree: 'ssr' });
this is my package.json:
"dependencies": {
"#babel/runtime-corejs2": "^7.5.1",
"apollo-boost": "^0.4.3",
"apollo-mocked-provider": "^3.0.1",
"babel-eslint": "^10.0.2",
"body-parser": "^1.19.0",
"clean-css": "^4.2.1",
"compression": "^1.7.4",
"dotenv-load": "^2.0.0",
"graphql": "^14.3.1",
"graphql-tag": "^2.10.1",
"helmet": "^3.18.0",
"morgan": "^1.9.1",
"next": "^9.0.1",
"next-plugin-custom-babel-config": "^1.0.2",
"next-transpile-modules": "^2.3.1",
"next-with-apollo": "^4.2.0",
"nprogress": "^0.2.0",
"path": "^0.12.7",
"react-apollo": "^3.0.0",
"react-cookie-consent": "^2.5.0",
"react-google-login": "^3.2.1",
"react-facebook-login": "^4.0.1",
"react-minimal-pie-chart": "^4.2.0",
"react-motion-drawer": "^3.1.0",
"supports-webp": "^2.0.1",
"express-device": "^0.4.2"
}
This is dev.conf in nginx (it's ok that ssl is commented out because the certificate comes from cloudfront):
server {
listen 80 default_server;
server_name staging.mysite.com;
include not_found.inc;
include static_resources.inc;
include ads.inc;
#include ssl.inc;
location / {
rewrite_log off;
include redirects/redirects.conf;
access_log /var/log/nginx/com-access.log combined;
error_log /var/log/nginx/com-error.log notice;
include graylog.logging;
include proxy_pass.inc;
auth_basic "closed site";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
Only the homepage works from serverside in my website however none other pages don't from serverside and return the handshake error from above. The homepage is a refreshhit from Cloudfront. Some pages open then when clicking on link clientside, however some don't open and result in 500 internal server error (handshake failure). So serverside never works but clientside sometimes works.
Nothing I tried has worked so far including changing AWS instance, removing headers/credentials from apollo client constructor, redeploying multiple times.
I see from the error stack that the error comes from here (node_modules/apollo-client/bundle.umd.js:92:26):
QueryManager.prototype.broadcastQueries = function () {
var _this = this;
this.onBroadcast();
this.queries.forEach(function (info, id) {
if (info.invalidated) {
info.listeners.forEach(function (listener) {
if (listener) {
listener(_this.queryStore.get(id), info.newData);
}
});
}
});
};
Why would the client not be able to broadcast queries?
I am a java developer for years and just new to the js world. This question sounds stupid but I don't know what's the proper/best way to build a dist for reactjs app for deploying to production(nginx/apache).
From my understanding, the dist just like simple web app and should looks like
contains:
index.html
client.js (bundled js after compiled)
static files, e.g.
images, css, js libraries, etc
I follow the guide on:
https://github.com/learncodeacademy/react-js-tutorials/tree/master/1-basic-react
and have a simple web app(maybe this is not called web app) running by:
npm run dev
it uses webpack to bundles the client.js.min and deploy to a embedded web server by node(maybe i am wrong).
Question:
How to build all the things by a command, say "npm run build" and it should built everything in a folder called "dist". So I can deploy it to web server root by copying every in dist to the web root.
package.json
{
"name": "react-tutorials",
"version": "0.0.0",
"description": "",
"main": "webpack.config.js",
"dependencies": {
"babel-core": "^6.17.0",
"babel-loader": "^6.2.0",
"babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-react-html-attrs": "^2.0.0",
"babel-plugin-transform-class-properties": "^6.3.13",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babel-preset-stage-0": "^6.3.13",
"react": "^0.14.6",
"react-dom": "^0.14.6",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.14.1"
},
"devDependencies": {},
"scripts": {
"dev": "webpack-dev-server --content-base src --inline --hot",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
webpack.config.js
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');
module.exports = {
context: path.join(__dirname, "src"),
devtool: debug ? "inline-sourcemap" : false,
entry: "./js/client.js",
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-decorators-legacy', 'transform-class-properties'],
}
}
]
},
output: {
path: __dirname + "/src/",
filename: "client.min.js"
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
};
In your scripts dictionary of package.json add the following
"build" : "NODE_ENV='production' && node_modules/.bin/webpack -p"
This will tell webpack to read the config file and build it in production mode i.e minify etc etc. The -p flag does it. The node env is to ensure that production build are used for react and other libraries and to set an env variable of production for NODE_Env
To run type. npm run build
I'm deploying my first webpack app. I probably have a few misconceptions.
My (simple) app is Webpack2 + Bootstrap4 + ReactJS.
I ran ... npm run prod (the optimizing sequence).
My "dist" folder now contains the files & folder that I list below.
I use DigitalOcean, Nginx, express, ... to deploy my Webpack app.
I uploaded my Webpack app into a directory that is in my DigitalOcean top directory.
In this directory named "wp2-bs4-rjs", I placed:
index.html, app.bundle.js, app.css, imgs (folder).
This "wp2-bs4-rjs" directory also contains:
package.json (for express) & node_modules folder (for express, for deployment).
I'm assuming my Webpack app does not use the node_modules folder,
now that it has been optimized (?).
IMPORTANT: When I use webpack-dev-server in my computer's localhost,
the Bootstrap & jQuery works (everything works).
BUT, when I view my Webpack app online, I see the text and its background image,
but no Bootstrap influence.
Since I see my background image & my css styles, I know the app.css file is properly working.
Also, since I see my text, I know my app.bundle.js file is partially working.
BUT, for some reason, the Bootstrap & jQuery in my app.bundle.js file is not working.
I have no errors in my JavaScript console & the networking tab.
Do you have any ideas of what I'm doing wrong ?
Here's it's URL: wp2-bs4-rjs
My Webpack app is served on my domain's localhost, port 3000, using reverse proxy.
- - - - - - - - - - - - - - - - - -
Thank-you, MLR
========================================================================
Update: I tried installing a few Node packages as dependencies,
to see if it made a difference. It did not.
Installed in my DigitalOcean server & my computer's webpack-dev-server (Webpack project):
"babel-cli": "^6.24.1", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "bootstrap": "^4.0.0-alpha.6", "express": "^4.15.3", "jquery": "^3.2.1", "react": "^15.6.1", "react-dom": "^15.6.1", "tether": "^1.4.0", "webpack": "^3.0.0"
- - - - - - - - - - - - - - - - - -
Not installed in my DigitalOcean server >Webpack project,
but is installed in my computer's webpack-dev-server version:
ejs, css-loader, style-loader, sass-loader, node-sass, extract-text-webpack-plugin, webpack-dev-server, babel-loader, babel-core, rimraf, file-loader, image-webpack-loader, libpng, bootstrap-loader, resolve-url-loader, url-loader, imports-loader exports-loader, postcss postcss-loader, purifycss-webpack, purify-css
========================================================================
Update: Since the node_modules folder is in the same directory as app.bundle.js ...
& all the other (non-image) files, ...
in the app.bundle.js, I tried changing all occurrences of ./node_modules to node_modules.
It did not work. Although my problem could be a combination of errors.
========================================================================
Hi olore, here's my Webpack config (as you asked).
'use strict';
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const glob = require('glob');
const PurifyCSSPlugin = require('purifycss-webpack');
const isProd = process.env.NODE_ENV === 'production';
const cssDev = ['style-loader','css-loader', 'resolve-url-loader', 'sass-loader'];
const cssProd = ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader','sass-loader'],
publicPath: '/dist'
});
let cssConfig = isProd ? cssProd : cssDev;
module.exports = {
entry: {
app: './src/app.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js'
},
resolve: { extensions: ['.js','.jsx','.html','.css','.scss'] },
module: {
rules: [{
test: /\.scss$/,
use: cssConfig// potentially the ExtractTextPlugin.extract(...)
},{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/
},{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
'file-loader?name=[name].[ext]&outputPath=imgs/&publicPath=./',
'image-webpack-loader'
]
},{
test: /\.(woff2?|svg)$/,
use: 'url-loader?limit=10000&name=fonts/[name].[ext]'
},{
test: /\.(ttf|eot)$/,
use: 'file-loader&name=fonts/[name].[ext]'
},{
test: /bootstrap[\/\\]dist[\/\\]js[\/\\]umd[\/\\]/,
use: 'imports-loader?jQuery=jquery'
}
],
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
hot: true,
open: true,
stats: 'errors-only'
},
plugins: [
new HtmlWebpackPlugin({
title: 'ReactJS Webpack Bootstrap',
hash: true,
template: './index.html',
minify: {collapseWhitespace: true}
}),
new ExtractTextPlugin({
filename: '[name].css',
disable: !isProd,
allChunks: true
}),
new PurifyCSSPlugin({
paths: glob.sync(path.join(__dirname, 'index.html')),
purifyOptions: { minify: true }
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
Tether: "tether",
"window.Tether": "tether",
Alert: "exports-loader?Alert!bootstrap/js/dist/alert",
Button: "exports-loader?Button!bootstrap/js/dist/button",
Carousel: "exports-loader?Carousel!bootstrap/js/dist/carousel",
Collapse: "exports-loader?Collapse!bootstrap/js/dist/collapse",
Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown",
Modal: "exports-loader?Modal!bootstrap/js/dist/modal",
Popover: "exports-loader?Popover!bootstrap/js/dist/popover",
Scrollspy: "exports-loader?Scrollspy!bootstrap/js/dist/scrollspy",
Tab: "exports-loader?Tab!bootstrap/js/dist/tab",
Tooltip: "exports-loader?Tooltip!bootstrap/js/dist/tooltip",
Util: "exports-loader?Util!bootstrap/js/dist/util"
})
]
};
Normally in developer mode Webpack runs using HTTP. There is usually a web server serving content through HTTP and webpack using http/websockets on a separate port.
Is it possible to run the web server on https and webpack on https/websocket secure ?
See the webpack docs
There is a flag you can add to the webpack-dev-server command
webpack-dev-server --https
While the above answer is correct for cli, if you are not in the CLI, you could do something like this (in a gulp task):
var WebpackDevServer = require('webpack-dev-server');
new WebpackDevServer(webpack(WebpackDevConfig), {
https: true,
hot: true,
watch: true,
contentBase: path.join(__dirname, 'src'),
historyApiFallback: true
}).listen(1337, 'localhost', function(err, result) {
if (err) {
console.log(err);
}
console.log('Dev server running at https://localhost:1337');
});
this for TEST environment only:
you need to configure your webpack-dev-server as follows:
webpack-dev-server --https --cert ./cert.pem --key ./key.pem
The easiest work around is to generate a key with no passphrase (I don't know the security consequences of this! but this is for test only) .
To take the passphrase out of your key use this command:
$ openssl rsa -in key.pem -out newKey.pem
and use the new key in the previews configuration line
With webpack-dev-server --https you create a self-signed certificate. But it works not for all use cases.
Browsers will ask you for a security exception and show in the url bar that connection is not secure.
Therefore it is recommended to create a locally trusted development certificate for localhost with mkcert
Then use it via CLI:
webpack-dev-server --https --key C:/Users/User/localhost-key.pem --cert C:/Users/User/localhost.pem --cacert C:/Users/User/AppData/Local/mkcert/rootCA.pem
or configure devServer.https option in webpack.config.js:
devServer: {
https: {
key: fs.readFileSync('C:/Users/User/localhost-key.pem'),
cert: fs.readFileSync('C:/Users/User/localhost.pem'),
ca: fs.readFileSync('C:/Users/User/AppData/Local/mkcert/rootCA.pem')
}
}
mkcert creates .pem files in Unix format by default. So if you're on Windows you'll probably need convert them to Windows format using e.g. Notepad++
Tested on Windows (04/22/2021). Easy (no installations required).
1. Project configuration
In your project root run in Powershell (or CMD):
npx mkcert create-ca
npx mkcert create-cert
Your webpack.config.js:
devServer: {
// ...
https: {
key: fs.readFileSync("cert.key"),
cert: fs.readFileSync("cert.crt"),
ca: fs.readFileSync("ca.crt"),
},
// ....
},
2. Install certificate
Double-click on ca.crt > Install Certificate > ...
... > Current User > Place all certificates in the following store > Trusted Root Certification Authorities > ...
... > Finish > Yes
3. Check correct installation
Start > Type: "cert" > Manage User Certificates > ...
... > Trusted Root Certification Authorities > Certificates > Test CA
4. Reload & Test
Reload your browser, Start yout webpack dev server and check the SSL Certificate validity:
Additional steps
If you get this error:
You can add this configuration to your webpack.config.js:
devServer: {
// ...
// https: { ... }
disableHostCheck: true,
// ....
},
For more info:
https://webpack.js.org/configuration/dev-server/#devserverhttps
https://www.npmjs.com/package/mkcert
In my case I had to run all these commands to get the certificate:
openssl genrsa -out private.key 4096
openssl req -new -sha256 -out private.csr -key private.key
openssl x509 -req -days 3650 -in private.csr -signkey private.key -out private.crt -extensions req_ext
openssl x509 -in private.crt -out private.pem -outform PEM
And then finally:
npm run dev -- --open --https --cert private.pem --key private.key
I'm working on react project, Now wanted to add SSL certificate on this project and run my website with https so have followed below step:
In add https in webpack.config.js
devServer: {
https: true,
host: '0.0.0.0', // you can change this ip with your ip
port: 443, // ssl defult port number
inline: true,
historyApiFallback: true,
publicPath: '/',
contentBase: './dist',
disableHostCheck: true
}
Add SSL public certificate on package.json file If you didn't want to add a certificate on your package.json file then you have to add it on your webpack.config.js it is mandatory to add your certificate in your project either you can it on package.json file or webpack.config.js
For Package.json
scripts: {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"start": "webpack-dev-server --open --https --cert /path/to/private.crt --key /path/to/private.key"
}
OR webpack.config.js
devServer: {
https: true,
host: '0.0.0.0', // you can change this ip with your ip
port: 443, // ssl defult port number
inline: true,
https: {
key: fs.readFileSync('/path/to/private.pem'),
cert: fs.readFileSync('/path/to/private.pem'),
ca: fs.readFileSync('/path/to/private.pem')
}
historyApiFallback: true,
publicPath: '/',
contentBase: './dist',
disableHostCheck: true
}
Run npm start command on a terminal or you can also use pm2 start npm -- start
Had similar case when webapp was served from docker container which internally uses http, but traefik is serving app though https (multiple ports: 4000, 3000), so socket client was trying to connect to http://my.app.url:3000.
After spending a few hours to figure out a solution, came up with this in webpack 5:
devServer: {
client: {
port: ' ', //<--must be empty to eliminate the 3000 port for connecting to socket client
},
devMiddleware: {
writeToDisk: true,
},
transportMode: 'sockjs',
port: 3000, // port which is dev server opening for the sockets
...(process.env.DOCKER_DEV && {
host: '0.0.0.0',
firewall: false,
public: 'https://my.app.url', <-- HTTPS here
}),
},