Configure JSdoc wtih Webpack - javascript

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

Related

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()
]
};

Public assets is 404 on prod build (webpack)

I'm not really familiar with webpack and I have this issue where I can't access my assets on prod - it returns 404
I have this structure:
- repo
- public
- index.html
- images
- animals
- dog.png
- audio
- growl.mp3
- src
- index.js
... other files
Now on my index.js (or other files) I access the images by doing:
import { Loader, utils, Sprite, AnimatedSprite } from 'pixi.js'
loader
.add('images/animals/dog.png' )
.load(async () => {})
... other codes
And this works fine on local, but when I deploy on production It throws
Failed to load resource: the server responded with a status of 404 () - /images/animals/dog.png:1 Failed to load resource: the server responded with
My webpack looks like this:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CircularDependencyPlugin = require('circular-dependency-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
mode: isProd ? 'production' : 'development',
entry: './src/index.js',
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'build'),
publicPath: '/',
},
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
},
devtool: isProd ? 'cheap-module-eval-source-map' : 'source-map',
devServer: {
hot: true,
watchContentBase: true,
contentBase: [
path.resolve(__dirname, 'public'),
path.resolve(__dirname, 'build'),
],
publicPath: '/',
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
},
},
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: 'public/index.html',
}),
new CircularDependencyPlugin({
exclude: /a\.js|node_modules/,
failOnError: false,
cwd: process.cwd(),
}),
new CopyWebpackPlugin([
{ from: 'public/audio', to: 'audio' },
{ from: 'public/images', to: 'images' },
]),
],
}
Ok, so I figured it out.
It turns out that I just need to make all publicPath to '' (empty string)

Webpack: Issues with /src and /dist files because of the publicPath

When I run webpack-dev-server, with a publicPath of /dist, I'm able to see live-edits for my app (changes to html, styling, js). However, when I compile the app into a production build, the stylesheet and javascript load from /dist/main.css and /dist/main.js instead of from main.css and main.js
The problem seems to be with the publicPath setting. If I remove publicPath, the app compiles with main.css and main.js, but I'm not able to see live edits. However, if I keep publicPath: /dist I can see live edits, but now I get /dist/main.css and /dist/main.js
const path = require('path');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/js/app.js',
output: {
filename: 'main.bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist'
}, //js output object
module: {
rules: [
{
test: /\.scss$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
]
}, //sass to css
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['babel-preset-env']
}
}
]
} //babel
]
}, //module object
plugins: [
new MiniCssExtractPlugin({
filename: '[name].min.css',
chunkFilename: '[id].min.css'
}),
new BrowserSyncPlugin({
host: 'localhost',
port: 3000,
proxy: 'http://localhost:8080/dist'
}),
new HtmlWebpackPlugin({
template: './src/index.html',
/* minify: {
collapseWhitespace: true
}*/
}),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorPluginOptions: {
preset: ['default', {discardComments: {removeAll: true}}]
},
canPrint: true
})
] //plugins array
}

webpack is compile time is very slow

My webpack is going very slow when it starts and when theres a change - compiling. Actually making development very slow right now. I'm only using greensock as the vendor but nothing else. I'm using only a few images too.. not sure.
Here is the code:
const path = require('path');
var webpack = require('webpack');
var htmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
// const ASSET_PATH = process.env.ASSET_PATH || '/'; ,
//publicPath: '/dist'
var isProd = process.env.NODE_ENV === 'production';
var cssDev = ['style-loader', 'css-loader', 'sass-loader'];
const VENDOR_LIBS =['gsap'];
var cssProd = ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader', 'sass-loader'
],
publicPath: '/dist'
});
var cssConfig = isProd ? cssProd : cssDev;
module.exports = {
entry: {
index: './src/js/index.js',
vendor: VENDOR_LIBS
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[hash].js'
},
devServer: {
//contentBase: path.join(__dirname, "/dist"),
compress: true,
port: 3000,
hot: true,
stats: "errors-only",
open: true
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all'
}
}
}
},
module:{
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use:[
"style-loader" , "css-loader"
]
},
{
test: /\.scss$/,
use: cssConfig
},
{
test: /\.pug$/,
use: ['html-loader', 'pug-html-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: ['file-loader?name=[name].[ext]&outputPath=images/&publicPath=images/',
'image-webpack-loader'
]
},
{
test: /\.(eot|ttf|woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader?name=[name].[ext]&outputPath=fonts/&publicPath=fonts/'
}
]
},
plugins: [
new htmlWebpackPlugin({
title: '',
template: './src/index.html',
minify: {
collapseWhitespace: true
},
hash: true,
inject: true
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new ExtractTextPlugin({
filename: 'app.css',
disable: !isProd,
allChunks: true
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})
]
};
Here is the package.json scripts:
"scripts": {
"killallProcesses": "killall node && webpack-dev-server",
"start": "webpack-dev-server",
"dev": "webpack -d",
"prod": "npm run clean && NODE_ENV=production webpack -p",
"clean": "rimraf ./dist/* ",
"deploy-gh": "npm run prod && git subtree push --prefix dist origin gh-pages"
}
So, not sure what is wrong here but compile time is very slow - using greensock as vendor but nothing else.. So not sure why its so slow. Even when I start webpack its brutal slow.
Webpack version 4 came with a huge speed imporvements.
First, use this strategy to split your config files for production and for development. Just follow the idea, don't follow the configurations because some of them are outdated.
Your config is the new config schema, based on webpack 4, só i'm going to do some tweaks to the basic one, and you can split them using the strategy i've linked.
First: install mini-css-extract-plugin.
const path = require('path');
const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const isProd = process.env.NODE_ENV === 'production';
const cssDev = ['style-loader', 'css-loader', 'sass-loader'];
const cssProd = [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'];
const cssConfig = isProd ? cssProd : cssDev;
// content hash is better for production which helps increasing cache.
// contenthash is the hash generated given the content of the file, so this is going to change only if the content changed.
const outputFilename = isProd ? '[name].[contenthash].js' : 'name.[hash].js';
module.exports = {
entry: './src/js/index.js',
output: {
// dist folder is by default the output folder
filename: outputFilename
},
// this should go into the webpack.dev.js
devServer: {
//contentBase: path.join(__dirname, "/dist"),
compress: true,
port: 3000,
hot: true,
stats: "errors-only",
open: true
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
// this takes care of all the vendors in your files
// no need to add as an entrypoint.
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
module:{
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use:[MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.scss$/,
use: cssConfig
},
{
test: /\.pug$/,
use: ['html-loader', 'pug-html-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: ['file-loader?name=[name].[ext]&outputPath=images/&publicPath=images/',
'image-webpack-loader'
]
},
{
test: /\.(eot|ttf|woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader?name=[name].[ext]&outputPath=fonts/&publicPath=fonts/'
}
]
},
plugins: [
new htmlWebpackPlugin({
title: '',
template: './src/index.html',
minify: {
collapseWhitespace: true
},
hash: true,
inject: true
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new MiniCssExtractPlugin({
filename: 'app.css',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})
]
};
Try this one and let me know what you got.

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