im trying to bundle my web app with webpack in my express js app - javascript

im trying to build my express app with webpack and i got a lot of errors i tried a lot of configs but nothing works , im using nodejs with express and ejs templating this is my first time using it to create something , i need to build it so i can deploy it , but i couldnt with all these errors:
const express = require("express");
var minify = require("express-minify");
const MainRoute = require("./routes/index");
const driver = require("./routes/driver");
const session = require("express-session");
const MySQLStore = require("express-mysql-session")(session);
const mysql = require("mysql2");
const crypto = require("crypto");
const bcrypt = require("bcrypt");
const multer = require("multer");
const path = require("path");
const Chart = require('chart.js/auto');
const Canvas = require('canvas');
const ejs = require('ejs');
const fs = require('fs');
// define the include function
ejs.filters.include = function(file, data) {
const filePath = path.join(__dirname, file);
const fileContent = fs.readFileSync(filePath, 'utf8');
return ejs.render(fileContent, data);
};
const app = express();
app.use(
minify({
cache: false,
uglifyJsModule: null,
errorHandler: null,
jsMatch: /javascript/,
cssMatch: /css/,
jsonMatch: /json/,
sassMatch: /scss/,
lessMatch: /less/,
stylusMatch: /stylus/,
coffeeScriptMatch: /coffeescript/,
})
);
app.use("/uploads", express.static(path.join(__dirname, "uploads")));
//------ Routes -------//
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use("/", MainRoute);
app.use("/", driver);
// rest of the code
//---------- Server is on ---------//
app.listen(1000, () => {
console.log("Server is On!!");
});
and my webpack.config.js :
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'production',
resolve: {
fallback: {
path: require.resolve("path-browserify"),
fs: false,
tls:false,
net:"empty",
"less": require.resolve("less"),
"vm": require.resolve("vm-browserify"),
"vm": false ,
https: require.resolve('https-browserify'),
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("stream-browserify"),
zlib: require.resolve("browserify-zlib"),
assert: require.resolve("assert/"),
buffer: require.resolve("buffer/"),
process: require.resolve("process/browser"),
url: require.resolve("url/"),
os: require.resolve("os-browserify/browser"),
"timers": require.resolve("timers-browserify"),
"http": require.resolve("stream-http"),
"constants": require.resolve("constants-browserify"),
},
},
entry: {
server: './server.js'
},
output: {
path: path.resolve(__dirname, 'public'),
filename: '[name].js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-stage-2']
}
}
},
{
test: /\.ejs$/,
loader: 'ejs-loader',
options: {
esModule: false
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './views/index.ejs',
hash: true,
})
],
node: {
__dirname: false
},
target: 'node'
};
im new to nodejs i hope you guys would help me!
i tried to change the webpack configs and install all the dependencies
ERROR in ./server.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: [BABEL] C:\Users\anasa\Desktop\ADROAD\server.js:
As of v7.0.0-beta.55, we've removed Babel's Stage presets.
Please consider reading our blog post on this decision at
https://babeljs.io/blog/2018/07/27/removing-babels-stage-presets
for more details. TL;DR is that it's more beneficial in the
long run to explicitly add which proposals to use.
For a more automatic migration, we have updated babel-upgrade,
https://github.com/babel/babel-upgrade to do this for you with
"npx babel-upgrade".
If you want the same configuration as before:
{
"plugins": [
// Stage 2
["#babel/plugin-proposal-decorators", { "legacy": true }],
"#babel/plugin-proposal-function-sent",
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-numeric-separator",
"#babel/plugin-proposal-throw-expressions",
// Stage 3
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-syntax-import-meta",
["#babel/plugin-proposal-class-properties", { "loose": false }],
"#babel/plugin-proposal-json-strings"
]
}
If you're using the same configuration across many separate projects,
keep in mind that you can also create your own custom presets with
whichever plugins and presets you're looking to use.
module.exports = function() {
return {
plugins: [
require("#babel/plugin-syntax-dynamic-import"),
[require("#babel/plugin-proposal-decorators"), { "legacy": true }],
[require("#babel/plugin-proposal-class-properties"), { "loose": false }],
],
presets: [
// ...
],
};
};
(While processing: "C:\\Users\\anasa\\Desktop\\ADROAD\\node_modules\\#babel\\preset-stage-2\\lib\\index.js")
ERROR in Template execution failed: ReferenceError: _ is not defined
ERROR in ReferenceError: _ is not defined
- index.ejs:10 module.exports
C:/Users/anasa/Desktop/ADROAD/views/index.ejs:10:26
- index.js:450
[ADROAD]/[html-webpack-plugin]/index.js:450:16
- task_queues:95 process.processTicksAndRejections
node:internal/process/task_queues:95:5
- async Promise.all
webpack 5.75.0 compiled with 3 errors in 1650 ms

Probably you're using a deprecated stage preset.
Try to fix it with this:
1 - Install the right preset:
npm install --save-dev #babel/preset-env
2 - If you have a babel config file like .babelrc or babel.config.js make it use this preset instead, or update your webpack plugin instead:
{
"presets": [
["#babel/preset-env", {
"targets": {
"node": "current"
}
}]
]
}
3 - Remove the stage-0 and stage-1 presets from your Babel configuration.
Hope that help!

Related

Webpack erroring on mini-css-extract-plugin loader

When I try to use the loader for mini-css-extract-plugin webpack returns the following error:
/node_modules/mini-css-extract-plugin/dist/loader.js:122
for (const asset of compilation.getAssets()) {
^
TypeError: compilation.getAssets(...) is not a function or its return value is not iterable
I am requiring the plugin and invoking the loader in my prod config file:
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const path = require("path");
const common = require("./webpack.common");
const merge = require("webpack-merge");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = merge(common, {
mode: "production",
output: {
filename: "[name].[contentHash].bundle.js",
path: path.resolve(__dirname, "dist")
},
plugins: [
new MiniCssExtractPlugin({filename: "[name].[contentHash].css"}),
new CleanWebpackPlugin()
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
],
},
],
},
});
I have it included in my devDependencies:
"mini-css-extract-plugin": "^1.3.6",
But still I receive the error. I haven't found anything in the [documentation][1] to indicate what could be happening. Is there something I'm overlooking with this code?
Why would methods from loader.js be getting flagged as 'not a function?'
[1]: https://www.npmjs.com/package/mini-css-extract-plugin
I understand getAssets is only available since webpack 4.40.0 https://webpack.js.org/api/compilation-object/#getassets
You could try:
Update webpack version to at least 4.40.0
Downgrade min-css-extract-plugin to 1.3.0
I tried the second one, and worked for me, but upgrading webpack should work too.

Webpack watch is failing me

EDIT: It's now resolved. Got in to work this morning and thought "have you tried turning it on and off again?". So I did. Removed node_modules, reinstalled all packages - it worked. FML.
I'm upgrading to Webpack 4 and can't seem to get the watch to work.
When I run the watch script everything runs as expected the first time, but errors out during a file update.
The scripts I try:
"dev": "cross-env ENV=dev webpack --config config/bundling/webpack.config.js --mode=development",
"watch": "cross-env WATCH=true yarn run dev --watch"
(redundancies in the cross-env variables will be fixed later)
The errors I get are the following:
"WARNING in configuration
The 'mode' option has not been set, webpack will fallback to
'production' for this value. Set 'mode' option to 'development' or
'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior.
Learn more: https://webpack.js.org/concepts/mode/"
"ERROR in multi (webpack)-dev-server/client?http://localhost:8080 ./src
Module not found: Error: Can't resolve './src' in [MY PATH HERE]
# multi (webpack)-dev-server/client?http://localhost:8080 ./src main[1]"
It seems like it doesn't read my webpack.config.js or the mode variable the on watch? Also, it succeeds in building the bundle, leading me to thing this might be an issue solely with the built-in webpack-dev-server.
I've tried everything I can think of, changing the scripts, changing the syntax of the mode flag, setting mode in webpack.config.js, tried relative paths, tried absolute paths, tried different versions of webpack and webpack-dev-server, moved my config file to the project root, sacrificed a small CPU to the Gods of code - nothing works.
I've been at this for days without any progress. Any help would be appreciated.
Versions:
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
Config:
require('dotenv').config()
const CopyWebpackPlugin = require('copy-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const BrowserSyncPlugin = require('browser-sync-webpack-plugin')
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
const moduleRules = require('./module.rules')
const config = require('./editable.config')
module.exports = function() {
const isDev = !!(process.env.ENV === 'dev')
const isProd = !!(process.env.ENV === 'prod')
const doServe = !!(process.env.SERVE === 'true')
const doWatch = !!(process.env.WATCH === 'true')
const webpackConfig = {
// Set mode
mode: isProd ? 'production' : 'development',
// Entry points.
entry: config.entrypoints,
// JS output name and destination.
output: {
path: config.paths.public,
filename: config.outputs.javascript.filename
},
// External dependencies.
externals: config.externals,
// Custom resolutions.
resolve: config.resolve,
// Rules for handling filetypes.
module: {
rules: [
moduleRules.javascript,
moduleRules.sass,
moduleRules.fonts,
moduleRules.images,
]
},
// Plugins running in every build.
plugins: [
new FriendlyErrorsWebpackPlugin(),
new MiniCssExtractPlugin(config.outputs.css),
new CleanWebpackPlugin(config.paths.public, { root: config.paths.root }),
new CopyWebpackPlugin([{
context: config.paths.images,
from: {
glob: `${config.paths.images}/**/*`,
flatten: false,
dot: false
},
to: config.outputs.image.filename,
}]),
new CopyWebpackPlugin([{
context: config.paths.fonts,
from: {
glob: `${config.paths.fonts}/**/*`,
flatten: false,
dot: false
},
to: config.outputs.font.filename,
}]),
],
devtool: isDev ? config.settings.sourceMaps : false,
watch: doWatch
}
// Set BrowserSync settings if serving
if (doServe) {
// setting our default settings...
const browserSyncSettings = {
host: 'localhost',
port: 3000,
proxy: process.env.HOME,
files: [
{
match: ['../../**/*.php'],
fn: function (event, file) {
if (event === 'change') {
this.reload()
}
}
}
]
}
// ...and overwriting them with user settings
Object.assign(browserSyncSettings, config.settings.browserSync)
webpackConfig.plugins.push(new BrowserSyncPlugin(browserSyncSettings))
}
return webpackConfig;
}
Config, part 2
const path = require('path')
module.exports = {
paths: {
root: path.resolve(__dirname, '../../'),
public: path.resolve(__dirname, '../../public'),
src: path.resolve(__dirname, '../../src'),
javascript: path.resolve(__dirname, '../../src/js'),
sass: path.resolve(__dirname, '../../src/sass'),
fonts: path.resolve(__dirname, '../../src/fonts'),
images: path.resolve(__dirname, '../../src/images'),
relative: '../../',
external: /node_modules/
},
entrypoints: {
main: ['./src/js/app.js', './src/sass/style.scss']
},
outputs: {
javascript: { filename: 'js/[name].js' },
css: { filename: 'css/[name].css' },
font: { filename: 'fonts/[path][name].[ext]' },
image: { filename: 'images/[path][name].[ext]' }
},
externals: {
},
resolve: {
},
settings: {
sourceMaps: 'cheap-module-source-map',
autoprefixer: {
browsers: ['last 3 versions', '> 1%', 'ie >= 10'],
},
browserSync: {
host: 'localhost',
port: 3000
}
}
}
Bonus question: is it possible to watch without having Webpack 4 start up a new devServer?
Thanks! <3

Webpack dev server not recompiling when files change

I have a project that's broken into 3 parts: a server and two webpack bundled web clients (App and Admin). The two web clients use basically the same webpack config with slight changes for setting output directories and dev server ports. Each client has its own package.json with a watch script that just runs webpack-dev-server.
The watch script on both clients succeed: the app builds and is accessible in a web browser. However, one of the clients (the Admin site) doesn't ever rebuild when changes are made, and seems to be constantly using an old build (webpack-dev-server hosts an old build even after restarting). The other client rebuilds fine.
What is happening here? They're configured almost exactly the same, they use the same plugins/loaders/etc, they're using similar libraries (React, mobx, etc).
Here's the base webpack config:
const webpack = require('webpack');
const path = require('path');
const { merge } = require('lodash');
const loaderUtils = require('loader-utils');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const env = process.env['NODE_ENV'];
const clientsRootDir = __dirname;
const defaultConfig = {
buildDir: 'dist',
entry: 'src/entry.js',
server: 'http://localhost:8000',
devServerPort: 8080,
constants: {
NODE_ENV: env,
PRODUCTION: env === 'production',
DEVELOPMENT: env === 'development',
DEBUG: env === 'development',
TEST: env === 'test',
LOG_LEVEL: env === 'production' ? 'error' : 'debug'
},
globalModules: {
React: 'react',
log: 'shared/log',
},
};
module.exports = (config) => {
config = merge({}, defaultConfig, config);
const { rootDir } = config;
const local = file => path.resolve(rootDir, file);
return {
devtool: 'eval-source-map',
entry: local(config.entry),
output: {
path: local(config.buildDir),
filename: 'bundle.js',
},
resolve: {
modules: [
'node_modules',
local('src'),
path.join(clientsRootDir, 'Shared')
],
},
module: {
rules: [
{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
{test: /\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$/, use: [
{loader: 'file-loader'},
]},
{
test: /\.s?css$/,
loader: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{loader: 'css-loader', options: {
modules: true,
importLoaders: 1,
localIdentName: '[path]_[local]',
}},
{loader: 'sass-loader'},
{loader: 'postcss-loader'},
],
}),
},
],
},
plugins: [
new ExtractTextPlugin('style.css', { allChunks: true }),
new webpack.ProvidePlugin(config.globalModules),
new webpack.DefinePlugin(config.constants),
new HtmlWebpackPlugin({
hash: true,
filename: 'index.html',
template: './src/index.html',
}),
],
devServer: {
port: config.devServerPort,
proxy: {
'/api': config.server
},
},
};
};
The working App webpack.config.js:
module.exports = require('../webpack.base.config')(Object.assign(
{rootDir: __dirname},
require('./config'),
));
And the app config:
module.exports = {
appId: 'com.company.app',
server: 'http://localhost:8000',
buildDir: 'www',
devServerPort: 8080,
};
The broken Admin webpack.config.js:
module.exports = require('../webpack.base.config')(Object.assign(
{rootDir: __dirname},
require('./config'),
));
And the admin config:
module.exports = {
appId: 'com.company.app_admin',
server: 'http://localhost:8000',
buildDir: '../../Server/public/admin',
devServerPort: 8081,
};
It ended up being some kind of folder renaming issue. I had moved the entire project and re-cloned while I had an iterm session open in the Admin folder. Either iterm or zshell got confused because pwd showed the correct path, but the branch zshell was displaying was incorrect. Running cd . corrected the branch zshell was displaying, and the watch script works fine now.
So the real issue was I was running watch in the wrong project even though my shell was telling me I was in the right project.
I had the same issue and SimpleJ's answer seems to have given me the hint I needed. I had a file SomeFolder/someFile.js, but it was being imported as ../somefolder/somefile (all lowercase).
Changing the capitalization in the import statement to match that of the actual folder and file seems to have remedied the issue.

webpacker not working correctly on heroku

I'm in the middle of upgrading an app from rails 3.2 to rails 4.2 using webpacker gem everything works fine in localhost I have compiled my assets and run
RAILS_ENV=production rails s
but I have errors when pushing to heroku it compiles all assets even the packs but generates errors in js, I use angular in many parts of the app and the error is related with dependency injection
check link
The main problem here was the unglifier gem I had to coment the uglifier
#config.assets.js_compressor = :uglifier
The next part was the configuration for webpack in production that look like this:
const webpack = require('webpack')
const { basename, dirname, join, relative, resolve } = require('path')
const merge = require('webpack-merge')
const CompressionPlugin = require('compression-webpack-plugin')
const sharedConfig = require('./shared.js')
const { env, settings, output, loadersDir } = require('./configuration.js')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const ManifestPlugin = require('webpack-manifest-plugin')
module.exports = merge(sharedConfig, {
output: { filename: '[name]-[chunkhash].js' },
devtool: false,//'source-map',
stats: 'normal',
plugins: [
new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
new ExtractTextPlugin({
filename: '[name]-[hash].css',
allChunks: true
}),
new ManifestPlugin({
publicPath: output.publicPath,
writeToFileEmit: true
})
],
resolve: {
extensions: settings.extensions,
modules: [
resolve(settings.source_path),
'node_modules'
],
alias: {
'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
},
resolveLoader: {
modules: ['node_modules']
}
})
Now I can deploy and the assets are working.

Webpack dev server not auto-reloading

So I've setup webpack and webpack-dev-server, but webpack-dev-server does not auto-reload. If i modify a file and save it there is no change in the browser until I manually refresh.
Here is my webpack config and my script file that runs webpack-dev-server. Does anyone see anything that could be preventing auto-reload from working?
I put these together by reading through multiple tutorials, the docs, and by reading through the react-create-app generated files.
config/webpack.config.dev.js
'use strict';
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer');
const webpack = require('webpack');
const extractSass = new ExtractTextPlugin('style.css');
module.exports = {
entry : './src/index.jsx',
eslint: {configFile: './src/.eslintrc.json'},
module: {
loaders: [
{
exclude: /node_modules/,
include: ['src'],
loader: 'babel',
test : /(\.js|\.jsx)$/
},
{
exclude: /node_modules/,
include: ['src']
loader : extractSass.extract([ 'css', 'postcss', 'sass' ]),
test : /\.scss$/
}
],
preLoaders: [
{
exclude: /node_modules/,
loader : 'eslint',
query : {presets: [ 'react', 'latest' ]},
test : /(\.js|\.jsx)$/
}
]
},
output: {
filename : 'bundle.js',
path : 'dist',
publicPath: '/'
},
plugins: [
extractSass,
new HtmlWebpackPlugin({
inject : true,
template: paths.appHtml
}),
new webpack.HotModuleReplacementPlugin({multistep: true})
],
postcss: () => [
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9'
]
})
]
};
scripts/dev.js
run with $ yarn run dev
'use strict';
const WebpackDevServer = require('webpack-dev-server');
const config = require('../config/webpack.config.dev.js');
const webpack = require('webpack');
const compiler = webpack(config);
const server = new WebpackDevServer(compiler, {
clientLogLevel : 'warn',
compress : true,
contentBase : 'public',
filename : config.output.filename,
historyApiFallback: true,
hot : true,
inline : true,
lazy : false,
noInfo : true,
publicPath : '/',
quiet : true,
stats : 'errors-only',
watchOptions : {
aggregateTimeout: 300,
poll : 1000
}
});
server.listen(8080, 'localhost', () => {
console.log('Listening on port 8080');
});
According to the webpack dev server documentation you should add this entry point to the webpack configuration to support automatic refresh.
config.entry.unshift("webpack-dev-server/client?http://localhost:8080/");
jontem pointed out in his answer that my config was missing a webpack-dev-server client.
Here's the steps I took to apply his solution and also setup HMR.
config/webpack.config.dev.js
module.config = {
// ...
entry: [
// converted entry to an array
// to allow me to unshift the client later
path.resolve(__dirname, '../src/index.jsx')
],
// ...
module: {
loaders: {
// ...
{
// Use style loader instead of ExtractTextPlugin
// To allow for style injection / hot reloading css
exclude: /node_modules/,
loaders: [ 'style', 'css', 'postcss', 'sass' ],
test : /\.scss$/
},
// ...
}
}
}
scripts/dev.js
'use strict';
const WebpackDevServer = require('webpack-dev-server');
const config = require('../config/webpack.config.dev.js');
const webpack = require('webpack');
// unshift `webpack-dev-server` client
// and hot dev-server
config.entry.unshift('webpack-dev-server/client?/', 'webpack/hot/dev-server');
const compiler = webpack(config);
// ...
I had the same issue and the following configuration enabled static and the in-memory bundle auto-reloading. The key is to enable devServer.watchContentBase.
config/webpack.config.dev.js
...
module.exports = {
...
devServer: {
contentBase: ...,
publicPath: ...,
watchContentBase: true
},
...
}
package.json
{
...
"scripts": {
"develop": "webpack-dev-server --open --mode development --config config/webpack.config.dev.js",
...
}
...
}
Please add the following in your webpack config and try.
devServer: {
hot: true,
inline: true,
host: "localhost",
port: 8082,
watchOptions: {
poll: true
}
}
note: I was using webpack version ^3.11.0
I had a similar problem, fixed it by adding
watchOptions: {
poll: true
}
When I first installed the webpack starter, everything worked flawlessly, after a week of changes to webpack.config.js, it stopped working. I tinkered with various recommendations, the one that worked was watchOptions: {poll:true }
FYI I am webpack 4 with "webpack": "4.29.6", "webpack-cli": "^3.3.0", "webpack-dev-server": "3.3.1"
devServer: {
port: 3000,
contentBase: './',
watchOptions: {
poll: true
}
}
Also
if you use extract-loader, auto reload will not work
Hot Module Replacement feature
devServer: {
// ,,,
contentBase: '/your/path'
watchContentBase: true
hot: true,
},
prevents refresh your static files in web page, unless you press F5 button in browser
This third party webpack dev server documentation has the answer that I needed:
https://wohugb.gitbooks.io/webpack/content/dev_tools/webpack-dev-server.html
The relevant section reproduced below:
There is no inline: true flag in the webpack-dev-server configuration, because the webpack-dev-server module has no access to the webpack configuration. Instead the user have to add the webpack-dev-server client entry point to the webpack configuration.
To do this just add webpack-dev-server/client?http://: to (all) entry point(s). I. e. with the above configuration:
var config = require("./webpack.config.js");
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080");
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {...});
server.listen(8080);
I also had the same issue and after adding this code line my problem solved. Now auto reloading worked
devServer : {
contentBase : './',
watchOptions : {
poll: true
}
}
For anyone experiencing this with Webpack v5, you need to set target to web in your config, like so:
module.exports = {
entry: "...",
target: "web",
.....
}

Categories

Resources