Unable to merge files using RequireOptimizer - requirejs

I want to merge files using the Require Optimizer, which I'm not able to do because of an error:
Here's the folder structure:
-build
-r.js
-build.js
-server
-app.js
-src
-clientConnectivity
-Upload.js
Here's build.js
({
baseUrl: "..",
paths: {
uploadManager: "./server/src/clientConnectivity/Upload"
},
include: uploadManager,
name: "server/app",
out: "main-built.js"
})
Here's the command passed and the error received:
C:\Users\Anjan\WebstormProjects\RequireOptimizerTest\build>node r.js -o build.js
Error: Error: Build file C:/Users/Anjan/WebstormProjects/RequireOptimizerTest/build/build.js is malformed: ReferenceError: uploadManager is not defined
at Function.build.createConfig (C:\Users\Anjan\WebstormProjects\RequireOptimizerTest\build\r.js:26541:23)
Here are the imports in app.js. I expect the Require Optimizer to read these imports in app.js and accordingly merge the called files.
import express = require('express');
import http = require('http');
import path = require('path');
import fs = require('fs');
import uploadModule = require('./src/clientConnectivity/Upload');

Here is a fixed example:
({
baseUrl: "..",
name: "server/app",
out: "main-built.js",
mainConfigFile : 'path/to/main.js',
findNestedDependencies: true
})

Related

Node/Webpack: Load package.json with ES6

I want to load my package.json in an ES6 environment and access it like pkg.name.
My solution so far is making a simple module for reading the file with fs, parsing it and import this module in every place I need to access it.
The problem is, I want to bundle my script with webpack and the path to the package.json is resolved to my current path from my pc I bundle everything. Like: D:/dev/app-name/package.json
This is wrong, I need a way to run the bundled script afterwards on e.g. a separate pc, or linux and still find the package.json. Is there a way to tell webpack to not resolve this path, or is there another (simpler) way to use the "root" path in my script?
My bundled app is an express server and I'm using webpack 5.
src/api/package-json.js:
import path from 'path'
import { fileURLToPath } from 'url'
import fs from 'fs-extra'
// Path CONST
// we need to change up how __dirname is used for ES6 purposes
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const PROJECT_ROOT = path.join(__dirname, '..', '..')
const PKG_FILE = path.join(PROJECT_ROOT, 'package.json')
// Package.json
const pkg = JSON.parse(fs.readFileSync(PKG_FILE)) // import pkg from '~root/package.json'
export default pkg
src/api/app.js:
import pkg from './package-json.js'
console.log(pkg.name)
webpack.config.js:
import path from 'path'
import { fileURLToPath } from 'url'
// import nodeExternals from 'webpack-node-externals'
// we need to change up how __dirname is used for ES6 purposes
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const { NODE_ENV = 'production' } = process.env
export default {
entry: './src/api/app.js',
mode: NODE_ENV,
target: 'node',
node: {
global: false,
__filename: false,
__dirname: false
},
output: {
path: path.resolve(__dirname, 'dist', 'server'),
filename: 'app.cjs'
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx']
},
externals: {
'node-pty': 'commonjs2 node-pty'
}
}
I found a workaround with process.cwd(), but I don't think this is a good solution for my problem. The problem is, process.cwd() can be changed in runtime as far as I know. :(
src/api/package-json.js:
import path from 'path'
import fs from 'fs-extra'
// Path CONST
const PROJECT_ROOT = process.cwd()
const PKG_FILE = path.join(PROJECT_ROOT, 'package.json')
// Package.json
const pkg = JSON.parse(fs.readFileSync(PKG_FILE)) // import pkg from '~root/package.json'
export default pkg

How can i import additional files into server.js using sapper?

In my sapper app, i try to import a file into the server.js file like this:
import sirv from 'sirv';
import polka from 'polka';
import compression from 'compression';
import * as sapper from '#sapper/server';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
const pushController = require('./backend/controllers/push');
polka()
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
sapper.middleware()
)
.post('/something/route', pushController.subscribe)
.listen(PORT, err => {
if (err) console.log('error', err);
});
But i always get the Error on console:
Error: Cannot find module './backend/controllers/push
my root folder looks like this:
- src
- backend
- controllers
- push.js
- client.js
- server.js
- service-worker.js
- template.html
I am using sapper with the default rollup config. Could the error therefore be related to rollup? How can I fix it?
A quick test shows it's ok with your structure. Please make sure you have
# push.js
function pushController() {
...
}
...
module.exports = { pushController }
and use import instead of require
# server.js
import { pushController } from './backend/controllers/push'

Can't resolve 'fs' in nextjs with custom express server

I add fs to my nextjs project and received the following error:
Module not found: Can't resolve 'fs' in '/Users/neven/Development/next-js/node_modules/dotenv/lib'
I found that to resolve this issue, I should add config.node = { fs: 'empty' } to my next.config.js file.
The problem is that when I add that config param, dotenv plugin stops working, that is env variables are not loaded on client side.
This is my next.config.js file, which works without any issues.
const withCSS = require('#zeit/next-css')
const dotenv = require('dotenv')
const path = require('path')
const Dotenv = require('dotenv-webpack')
dotenv.config()
module.exports = withCSS({
webpack: config => {
config.plugins = config.plugins || []
config.plugins = [
...config.plugins,
// Read the .env file
new Dotenv({
path: path.join(__dirname, '.env'),
systemvars: true,
}),
]
return config
},
})
And then when I add fs: 'empty', it looks like this:
const withCSS = require('#zeit/next-css')
const dotenv = require('dotenv')
const path = require('path')
const Dotenv = require('dotenv-webpack')
dotenv.config()
module.exports = withCSS({
webpack: config => {
config.plugins = config.plugins || []
config.node = {
fs: 'empty'
}
config.plugins = [
...config.plugins,
// Read the .env file
new Dotenv({
path: path.join(__dirname, '.env'),
systemvars: true,
}),
]
return config
},
})
Do you have any suggestions on how I could work this thing out?
Let me know in case additional details are needed.
I found out what the issue was; dotenv plugin is working correctly, but I was trying to get the variables on client side, and that is not possible in this way.
The solution to use env variables on client side is to add env: { EXAMPLE: 'helloWorld' } to next.config.js file.
const withCSS = require('#zeit/next-css')
const dotenv = require('dotenv')
const path = require('path')
const Dotenv = require('dotenv-webpack')
dotenv.config()
module.exports = withCSS({
env: { EXAMPLE: 'helloWorld' },
webpack: config => {
config.plugins = config.plugins || []
config.node = {
fs: 'empty'
}
config.plugins = [
...config.plugins,
// Read the .env file
new Dotenv({
path: path.join(__dirname, '.env'),
systemvars: true,
}),
]
return config
},
})
The issue here is that your client-side can't access the environment variables.
Started NextJS 9.4, you can use .env* files to add your environment variables.
For your client-side to get access access to the environment variables, you just need to prefix them with NEXT_PUBLIC_
NEXT_PUBLIC_YOUR_KEY="keykeykey"
These can be accessible with:
process.env.NEXT_PUBLIC_YOUR_KEY

How to include readline in webpack

I have created nodejs console app and trying to minify it with webpack.
webpack.config.js I got:
const path = require('path');
module.exports = {
externals: {
fs: "require('fs')",
readline: "require('readline')",
},
entry: './index.js',
output: {
path: path.resolve(__dirname, 'bin'),
filename: 'bin.js'
},
mode: 'development'
};
Everything goes ok before I run builded app:
readline.js:189
input.on('data', ondata);
^
TypeError: input.on is not a function
at new Interface (readline.js:189:11)
at Object.createInterface (readline.js:69:10)
What should I do to prevent this error?
Somewhere I found the solution. In the webpack configuration file I must set target: node to point the collector what to do with standard external packages (e.g. readline, fs, path, etc.).

webpack-dev-middleware and Express - can't get them to collaborate

I am trying to set up my first project using Webpack and Express but somehow I am doing something wrong.
This is what I did:
1. CREATED SAMPLE PROJECT
Created a sample project using express-generator. My folder structure is something like:
express-project
-app.js
-webpack.config.js
-public
-javascripts
-modules
-build
2. SET UP HANDLEBARS
Set up handlebars as view/template engine and created a couple of routes
3. WEBPACK CODE
Created the Webpack specific code/configuration as follows
webpack.config.js
var webpack = require('webpack');
var path = require('path');
var webpackHotMiddleware = 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&overlay=false';
module.exports = {
resolve: {
alias: {
handlebars: path.resolve('public/vendor/handlebars-v4.0.5.js'),
bootstrap: path.resolve('public/vendor/bootstrap/js/bootstrap.js'),
pubsub: path.resolve('public/vendor/ba-tiny-pubsub.js')
}
},
context: path.resolve('public/javascripts'),
entry: {
cart: ['./modules/cart', webpackHotMiddleware],
index: ['./modules/products.js', webpackHotMiddleware],
vendor: ['bootstrap', 'pubsub', webpackHotMiddleware]
},
output: {
path: path.resolve('public/javascripts/build'),
publicPath: 'javascripts/build/',
filename: '[name].js',
chunkFilename: "[id].js"
},
module: {
loaders: [
// some loaders here
]
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
}
app.js
// some code before
var app = express();
(function() {
// Step 1: Create & configure a webpack compiler
var webpack = require('webpack');
var webpackConfig = require(process.env.WEBPACK_CONFIG ? process.env.WEBPACK_CONFIG : './webpack.config');
var compiler = webpack(webpackConfig);
// Step 2: Attach the dev middleware to the compiler & the server
app.use(require("webpack-dev-middleware")(compiler, {
noInfo: false,
publicPath: webpackConfig.output.publicPath,
stats: {
colors: true
}
}));
// Step 3: Attach the hot middleware to the compiler & the server
app.use(require("webpack-hot-middleware")(compiler, {
log: console.log,
path: '/__webpack_hmr',
heartbeat: 10 * 1000
}));
})();
// some code after
4. JS CODE ON TEMPLATE
Then on the handlebars page I require the bundled javascripts
<script src="javascripts/build/common.js"></script>
<script src="javascripts/build/vendor.js"></script>
<script src="javascripts/build/cart.js"></script>
5. NPM START
Finally if I start the server using the standard npm start I see in the shell that webpack bundles everything with no errors but if I go to localhost:3000/ it does not find any of the assets created by Webpack. Instead if I run webpack to create the various bundles as if I were on production, everything is created correctly and it works as expected.
Hope someone can figure out what I am doing wrong.
Thanks
I managed to figure out what was causing the problem, by adding a slash in these 2 lines everything started to work properly:
context: path.resolve('public/javascripts/'),
path: path.resolve('public/javascripts/build/'),

Resources