When typing command "npm run dev" for webpack, it creates a folder that ends with NaN - javascript

i'm taking a course in Lynda.com "learning-full-stack-javascript-development-mongodb-node-and-react" and when i use the command "npm run dev" to create a bundle.js file in "public" folder, it creates a folder "publicNaN" and puts the file bundle.js in it.
i want it to be in the "public" folder.
here is the webpack.config.js file:
const path = require("path");
const BUILD_PATH = path.join(__dirname, "./public");
// See https://github.com/Microsoft/vscode/blob/master/extensions/shared.webpack.config.js
module.exports = {
mode: "production",
target: "node",
node: {
__dirname: false
},
entry: {
extension: ["./src/index.js"]
},
output: {
path: BUILD_PATH + + '/public',
filename: "bundle.js",
libraryTarget: "commonjs",
},
resolve: {
extensions: [".ts", ".js"]
},
externals: {
"vscode": "commonjs vscode"
},
module: {
rules: [
{
test: /\.ts$/,
use: [
{
loader: "ts-loader"
}
],
exclude: /node_modules/
},
{
test: /\.mjs$/,
type: "javascript/auto",
use: []
}
]
},
stats: {
children: false,
modules: false
}
};

You're already setting your BUILD_PATH to /public here:
const BUILD_PATH = path.join(__dirname, "./public");
So there's no need to add it in the output object. Also the two + signs tries to convert to a number. That's why you get NaN at the end.
So change the output object to this:
output: {
path: BUILD_PATH,
filename: "bundle.js",
libraryTarget: "commonjs",
},

Related

webpack - cannot find module from dist bundle

So I'm trying to require dynamically from my node application a dist asset. And I'm getting the following error:
{"applicationLog":{"severity":"ERROR","timestamp":"2022-08-05T06:54:57.275Z","exception":{"type":"Error","message":"Cannot find module '/Users/lekoma/evelin/product-listing-fragment/dist/modern/fragment.js'","stack":"Error: Cannot find module '/Users/lekoma/evelin/product-listing-fragment/dist/modern/fragment.js'\n at webpackEmptyContext (webpack://product-listing-fragment/./node_modules/#jsmdg/react-fragment-scripts/server/_sync?:2:10)\n at getFragment (webpack://product-listing-fragment/./node_modules/#jsmdg/react-fragment-scripts/server/fragmentSsrRouter.js?:84:98)\n at createFragmentSsrRouter (webpack://product-listing-fragment/./node_modules/#jsmdg/react-fragment-scripts/server/fragmentSsrRouter.js?:121:20)\n at eval (webpack://product-listing-fragment/./node_modules/#jsmdg/react-fragment-scripts/server/createServer.js?:142:5)\n at Plugin.exec (/Users/lekoma/evelin/product-listing-fragment/node_modules/avvio/plugin.js:132:19)\n at Boot.loadPlugin (/Users/lekoma/evelin/product-listing-fragment/node_modules/avvio/plugin.js:274:10)\n at processTicksAndRejections (node:internal/process/task_queues:83:21)","code":"MODULE_NOT_FOUND"},"message":"Could not read fragment entry point"}}
The dist folder structure looks like following:
/dist/modern/fragment.js
The output of the node generated code is in a different folder:
build/server/index.js
Do you know who I could achieve to read dynamically from the dist folder?
source code node index.js
function getFragment(fragmentAssets) {
try {
const { Fragment } = require(path.join(
paths.clientOutputDirectory,
MODERN_BROWSER_STAGE || 'modern',
getFragmentEntryPointFromAssets(fragmentAssets), // the resolving path is correct, but the module could not be found/interpreted
));
return Fragment;
} catch (error) {
unpreparedLogger.withException(error).error('Could not read fragment entry point');
process.exit(1);
}
}
webpack config
module.exports = function webpackServerConfig() {
return {
target: 'node', // in order to ignore built-in modules like path, fs, etc.
mode: 'development',
externalsPresets: { node: true }, // in order to ignore built-in modules like path, fs, etc
externals: [
nodeExternals({
allowlist: [/#jsmdg\/react-fragment-scripts\/.*/, /#jsmdg\/yoshi\/.*/]
})], // in order to ignore all modules in node_modules folder
entry: {
server: {
import: paths.serverEntry,
filename: 'server/index.js',
},
shared: {
import: paths.sharedEntry,
filename: 'shared/index.js',
},
},
resolve: {
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypescript || !ext.includes('ts')),
},
output: {
path: paths.BFFOutputDirectory,
clean: true,
},
optimization: {
minimize: isEnvProduction,
minimizer: [new TerserPlugin()],
},
module: {
strictExportPresence: true,
rules: [
{
oneOf: [
{
test: /\.(js|jsx|ts|tsx)$/,
include: [
paths.clientSourceDirectory,
paths.sharedSourceDirectory,
paths.serverSourceDirectory,
/node_modules\/(#jsmdg\/react-fragment-scripts|#jsmdg\/yoshi)\/.*/,
],
exclude: [
isEnvProduction ? /__mock/ : undefined,
].filter(Boolean),
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
presets: [[require.resolve('../babel/server')]],
},
},
],
},
],
},
};
};

Node project: trying to use the same ES6 code for both the front end and back end

I have a need to share front end and back end code in a single javascript project. The front end code is transpiled using babel and the back end code is a node script (not a web app) that runs on the server.
There's currently just a single package.json file in the project.
I'm using --experimental-vm-modules to run the node server script which allows me to use ES6 syntax and import statements, however it requires the javascript files to have an .mjs extension.
The catch-22 I'm running into is that the file that is meant to be shared between the FE and BE (sharedConstants.js) only works on the back end with an .mjs extension and only works on the client side with a .js extension.
Another solution I considered was to put 'type: module' in package.json file, but then this breaks the compilation of the client side app which uses webpack, babel, react, etc.
The project is currently using node version v14.18.0 but I'm open to considering an upgrade if that in some way helps to resolve this issue.
UPDATE:
Webpack version is 4.42.0 and #babel/core version is 7.2.2
(also added contents of .babelrc, webpack.config.babel.js and webpack.config.common.js)
Contents of .babelrc:
{
"plugins": [
"#babel/proposal-class-properties",
"#babel/plugin-syntax-dynamic-import",
"#babel/transform-runtime",
["import", { "libraryName": "antd", "libraryDirectory": "lib"}, "antd"],
["import", { "libraryName": "antd-mobile", "libraryDirectory": "lib"}, "antd-mobile"],
["babel-plugin-webpack-alias", { "config": "./webpack.config.common.js" }]
],
"presets": [
"#babel/preset-react", "#babel/preset-env"
],
"only": [
"./**/*.js",
"node_modules/jest-runtime"
],
"sourceType": "module"
}
Contents of webpack.config.babel.js:
let webpack = require('webpack');
let webpackCommon = require('./webpack.config.common.js');
module.exports = Object.assign({}, webpackCommon, {
mode: 'development',
entry: [
'./src/app-client.js',
/* The port on the development server must be entered in this section to
work properly. */
'webpack-dev-server/client?http://0.0.0.0:4000',
'webpack/hot/only-dev-server'
],
output: {
// Files are being written to disk so it's not certain at this point if
// they are being served from memory in a development environment.
// TODO: Confirm the performance impact of disk vs memory and if with the
// current configuration the files are being served from memory.
path: __dirname + '/public/',
filename: 'bundle.js'
},
devtool: 'source-map',
// dev server settings
devServer: {
hot: true,
filename: 'bundle.js',
publicPath: '/',
historyApiFallback: true,
contentBase: './public/index-static.html',
/* all requests are proxied to receive the response,
if it is bundle file, program uses script of dev server. */
proxy: {
'**': 'http://localhost:5000' // express server address
},
stats: {
// minimize console log
assets: false,
colors: true,
version: false,
hash: false,
timings: false,
chunks: false,
chunkModules: false
}
}
});
module.exports.plugins.push(new webpack.HotModuleReplacementPlugin());
Contents of webpack.config.common.js:
// Common webpack configuration.
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
const fs = require('fs');
const lessToJs = require('less-vars-to-js');
const antdThemeVarsOverride = lessToJs(
fs.readFileSync(
path.join(__dirname, './src/static/less/antd-theme-vars-override.less'),
'utf8'
)
);
const HTMLWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: ['./src/app-client.js', './src/static/less/main.less'],
output: {
path: __dirname + '/public/',
filename: 'bundle.js'
},
module: {
// NOTE! If you change the order of the rules, the end of the prod
// webpack config file must be changed as well!
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{loader: 'react-hot-loader/webpack'},
{
loader: 'babel-loader',
options: JSON.stringify({
babelrc: false,
cacheDirectory: true,
presets: ['#babel/preset-env', '#babel/react'],
plugins: [
'#babel/transform-runtime',
'#babel/proposal-class-properties',
'lodash',
['import', {libraryName: 'antd', style: true}, 'antd'],
[
'import',
{libraryName: 'antd-mobile', style: true},
'antd-mobile'
]
]
})
}
]
},
{
test: /\.modernizrrc.js$/,
use: ['modernizr-loader']
},
{
test: /\.modernizrrc(\.json)?$/,
use: ['modernizr-loader', 'json-loader']
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.less$/,
use: [
{loader: MiniCssExtractPlugin.loader},
{loader: 'css-loader'},
{
loader: 'less-loader',
options: {
modifyVars: antdThemeVarsOverride,
javascriptEnabled: true
}
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
}
]
},
resolve: {
modules: ['node_modules', path.join(__dirname, 'src')],
alias: {
Actions: path.resolve(__dirname, 'src/actions/'),
Components: path.resolve(__dirname, 'src/components/'),
Containers: path.resolve(__dirname, 'src/containers/'),
Db: path.resolve(__dirname, 'server/db/'),
Table: path.resolve(__dirname, 'src/components/HipocampoTable/'),
Js: path.resolve(__dirname, 'src/js/'),
Layouts: path.resolve(__dirname, 'src/components/layouts/'),
Reducers: path.resolve(__dirname, 'src/reducers/'),
Selectors: path.resolve(__dirname, 'src/selectors/'),
Server: path.resolve(__dirname, 'server/'),
Scripts: path.resolve(__dirname, 'scripts/'),
Spreadsheets: path.resolve(__dirname, 'spreadsheets/'),
Shared: path.resolve(__dirname, 'src/shared/'),
Slices: path.resolve(__dirname, 'src/slices/'),
Static: path.resolve(__dirname, 'src/static/'),
Support: path.resolve(__dirname, 'cypress/support/'),
modernizr$: path.resolve(__dirname, '.modernizrrc')
},
extensions: ['.js', '.json', '.less', '.jsx', '.css', '.sql']
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{from: './static/favicon.png', to: 'favicon.png'},
{from: './static/circle_logo.png', to: 'circle_logo.png'}
]
}),
new HTMLWebpackPlugin({
title: 'Hipocampo',
template: './static/index-template.html',
filename: 'index-static.html',
// This is needed to ensure that the password reset link works.
publicPath: '/',
minify: {
collapseWhitespace: false,
removeComments: false
}
}),
// This is to reduce the moment.js webpack size
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en-US/),
new MiniCssExtractPlugin()
]
};

Webpack 5 - Scss relative urls won't load images

I have my scss and my images in folders at the same level.
File structure
styles
app.scss
images
my-image.jpg
Am trying to import my image like so
app.scss
body {
background: url(../images/my-image.jpg);
}
I have a simple webpack configuration to load scss and images.
webpack.config.js
const path = require("path");
module.exports = {
entry: "./resources/index.js",
resolve: {
alias: {
resource: path.resolve(__dirname, "resources/images"),
},
},
output: {
path: path.resolve(__dirname, "dist"),
publicPath: "/dist",
filename: "main.js",
assetModuleFilename: "[name][ext][query]",
clean: true,
},
mode: "production",
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.(png|jpg)/,
type: "asset",
},
],
},
};
Later on I tried to use resolve-url-loader between css-loader and scss-loader which seemed promising. But also to no avail.
The build isn't throwing any errors. But the page doesn't open the image.
Thank you for any help you give me my bros and bronettes.
At the end the problem with the images was simply in the publicPath on the web.config.js file.
Changing it from dist/ to /dist did the job.
const path = require("path");
module.exports = {
...
output: {
path: path.resolve(__dirname, "dist"),
publicPath: "dist/", //This is where the issue was
filename: "main.js",
assetModuleFilename: "[name][ext][query]",
clean: true,
},
...
};
Let this be a warning for all ye who enter webpack.

Configure JSdoc wtih Webpack

I started my Webpack configuration last week, and a problem appear : How can I run a jsdoc generation with Webpack ?
All Jsdoc Webpack seems to be deprecated or out-to-date...
My simple configuration file :
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ESLintPlugin = require('eslint-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
let config = {
entry: {
app: ['./src/js/css.js', './src/js/app.js']
},
output: {
filename: 'assets/js/[name].[contenthash].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000,
},
mode: 'development',
// mode: 'production',
devtool: 'inline-source-map',
module: {
rules: [
// LOADER BABEL
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
targets: ['defaults'],
plugins: ['#babel/plugin-proposal-object-rest-spread']
}
}
},
// LOADER STYLE + CSS
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./index.html"
}),
new ESLintPlugin({
extensions: ["js", "jsx", "ts", "tsx"],
})
]
};
let analyzerMode = process.argv.find(param => param === '--analyze');
config.plugins.push(new BundleAnalyzerPlugin({
openAnalyzer: false,
defaultSizes: 'gzip',
analyzerMode: analyzerMode ? 'static' : 'disabled'
}));
module.exports = config;
Now, on my project, it's possible to run jsdoc src/js/, it will be generate out folder with all JS Documentation.
How can I automate this process command with webpack.config.js ?
You can append the command to the build script in package.json
{
"name": "your_project_name",
...
"scripts": {
"build": "webpack --mode production && jsdoc src/js/"
}
...
}
If you just want '.d.ts' files you can use npx tsc. It will do the work if tsconfig.json is properly configured like in the link below
https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html

Webpack Dev Server Not Hot Reloading .vue files

Been working on a project and was sure HMR was working, any of my .js files if I would update them webpack would compile and the module would be replaced all hot like.
I was working on a .vue file and webpack would recompile, but there was no super fresh HMR.
Hoping someone can take a look and tell me if something is off:
The script I'm using in the cli looks like this.
webpack-dev-server --d --watch --output-path ./public --config ./_src/webpack.config.js --progress --env.dev
I'm guessing the most important bit to look at is this:
devServer: {
contentBase: 'public',
hot: true,
filename: 'main.js',
overlay: true,
stats: { colors: true },
port: 3000,
proxy: {
'/': {
target: 'http://moment.local/',
secure: false,
changeOrigin: true
}
},
historyApiFallback: true
},
But here is my whole config if it helps.
const webpack = require('webpack')
const {resolve} = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = env => {
const addPlugin = (add, plugin) => add ? plugin : undefined
const ifProd = plugin => addPlugin(env.prod, plugin)
const removeEmpty = array => array.filter(i => !!i)
// Our Sass Extraction Plugin
const extractSass = new ExtractTextPlugin({
filename: 'style.css',
disable: env.dev
})
return {
entry: {
'vendor': ['jquery', 'KlaviyoSubscribe', 'learnq', 'select2', 'slick-carousel', 'moment', 'lodash'],
'main': resolve(__dirname, './js/index.js')
},
output: {
filename: '[name].js',
path: resolve(__dirname, '../public/'),
pathinfo: !env.prod
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: 'vue-style-loader!css-loader!postcss-loader!sass-loader', // <style lang='scss'>
scss: 'vue-style-loader!css-loader!postcss-loader!sass-loader', // <style lang='scss'>
sass: 'vue-style-loader!css-loader!postcss-loader!sass-loader?indentedSyntax' // <style lang='sass'>
}
}
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{ test: /\.s(c|a)ss$/,
use: extractSass.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
sourceMap: true
}
},
'postcss-loader?sourceMap',
'sass-loader?sourceMap'
]
})
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
devtool: env.prod ? 'source-map' : 'eval',
devServer: {
contentBase: 'public',
hot: true,
filename: 'main.js',
overlay: true,
stats: { colors: true },
port: 3000,
proxy: {
'/': {
target: 'http://moment.local/',
secure: false,
changeOrigin: true
}
},
historyApiFallback: true
},
bail: env.prod, // Fail out on the first error if production
resolve: {
alias: {
'vue$': 'vue/dist/vue.common.js'
}
},
plugins: removeEmpty([
extractSass,
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({
// Let's create js for our vendor scripts
name: 'vendor',
// (with more entries, this ensures that no other module
// goes into the vendor chunk)
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
filename: 'commons.js',
// (Modules must be shared between 2 entries)
minChunks: 2
})
...
])
}
}
Really struggling here so anything would be great.
It sounds like you want the "hot" behaviour but you are missing the --hot option in the script you posted. The documentation for that option is here.
You have a lot of options already; just add --hot and that should do the trick.
UPDATE:
I do see that you have the hot: true set in the devServer property of your webpack config, but if I don't use --hot in the cli, I get the following error in the console, so that is why I am saying to use it even though you would think it would be covered by the config - its not.
Uncaught Error: [HMR] Hot Module Replacement is disabled.
Add a file called vue.config.js in your root directory.
Inside it you can enable hot reloading via:
module.exports = {
devServer: {
watchOptions: {
poll: true
}
}
};
I used this settings in a project that was set up via vue create.

Categories

Resources