TreeShaking with RxJS 7.x and WebPack 5 - node.js

I would like to treeshake rxjs in my TypeScript application that is bundled via WebPack:
rxjs#7.5.7
webpack#5.74.0
According to https://rxjs.dev/guide/installation I would have to use the ES2015 exports of rxjs, but I cannot find out how to do that.
Are you aware of an example or a link to some documentation?
My current webpack config is:
const path = require('path');
module.exports = {
entry: './src/index.ts',
devtool: 'source-map',
target: 'node16',
mode: 'production',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
This config has successfully tree shaken the rxjs#6 version (which has the module entry point) but it fails to tree shake rxjs#7 and uses the full CJS version instead.
Thanks for any pointers!

Looks like this is a viable approach:
const path = require('path');
module.exports = {
entry: './src/index.ts',
devtool: 'source-map',
target: 'node18.12',
mode: 'development',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
conditionNames: ['es2015', 'import'],
mainFields: ['es2015', 'module', 'main'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};

Related

How do I ignore a an import in webpack?

I have a webpack file that looks like the one below, and I have a line in my handler.ts which looks like this:
import { PayoutEntity, IPayout, payoutEntityManager } from "/opt/nodejs/orm";
However I get the following error as the module/path for "/opt/nodejs/orm" doesn't exist locally:
Module not found: Error: Can't resolve '/opt/nodejs/orm'
The webpack build is for a lambda and the files for "/opt/nodejs/orm" are in a lambda layer that will only be accessable from the application once it's deployed to aws.
So in fact I would like webpack to ignore completely /opt/nodejs/orm and not even try to pack it.
I've tried using the ignore plugin with const ignore = new webpack.IgnorePlugin({resourceRegExp:/^(\/opt\/nodejs\/search|\/opt\/nodejs\/orm|\/opt\/nodejs\/put-event)$/}) but this just results in baking the "module not found" error into the bundled output file.
"use strict";
const path = require("path");
module.exports = {
devtool: "source-map",
entry: "./src/handler.ts",
mode: "production",
target: "node",
externals: [nodeExternals()],
node: {
__dirname: true,
},
output: {
filename: "index.js",
libraryTarget: "commonjs2",
path: path.resolve(__dirname, ".build"),
},
module: {
rules: [
{
test: /\.(graphql|gql)$/,
loader: "graphql-tag/loader",
exclude: /node_modules/,
},
{
test: /\.(tsx?)$/,
loader: "ts-loader",
exclude: [
[
path.resolve(__dirname, "node_modules"),
path.resolve(__dirname, ".serverless"),
path.resolve(__dirname, ".webpack")
],
],
options: {
transpileOnly: false,
experimentalWatchApi: true,
},
},
],
},
resolve: {
extensions: [".ts", ".tsx", ".js"],
},
};

Typescript library build

I am new with webpack and I am currently trying to build my library which is similiar to LINQ, Java 8 Stream API #szilanor/stream for npm.
Here is my webpack.config.ts
import {Configuration} from 'webpack';
import TerserPlugin from 'terser-webpack-plugin';
import * as path from 'path';
const config: Configuration = {
mode: 'production',
devtool: 'source-map',
entry: './src/index.ts',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'build'),
library: 'Stream',
libraryTarget: 'umd',
clean: true,
},
optimization: {
minimize: true,
minimizer: [new TerserPlugin({extractComments: false})],
},
module: {
rules: [
{
test: /\.([mjt])s$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
},
},
],
},
resolve: {
extensions: ['.ts', '.js', '.json'],
},
};
export default config;
as it show I am trying to create an 'umd' bundle with babel and generate the type definitions with tsc.
So my question is that is gonna work in every situation whatever project I am trying to use it in (for example angular, react, node...)? If not can you help me to fix it?

Error: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema

I'm getting this weird error when I'm trying to do a "npm run dev". First, I cloned a repo, then changed into that project folder where I did a "npm install".
After it was done, I tried the "npm run dev", but it gave me a long error:
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration[0].mode should be one of these:
"development" | "production" | "none"
-> Enable production optimizations or development hints.
- configuration[1].mode should be one of these:
"development" | "production" | "none"
-> Enable production optimizations or development hints.
My webpack.config.js file:
const path = require('path');
var nodeExternals = require('webpack-node-externals');
const serverConfig = {
mode: process.env.NODE_ENV || 'development',
entry: './src/server/server.ts',
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
configFile: 'tsconfig.server.json'
}
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
output: {
filename: 'server.js',
path: path.resolve(__dirname, 'dist')
},
target: 'node',
node: {
__dirname: false
},
externals: [nodeExternals()]
};
const clientConfig = {
mode: process.env.NODE_ENV || 'development',
entry: './src/client/index.tsx',
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
configFile: 'tsconfig.client.json'
}
},
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js', '.css', '.scss']
},
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'public/js')
}
};
module.exports = [serverConfig, clientConfig];

can't find the file that webpack production mode generated

The problem is:
If I set the mode to 'production', the js file will not show up in build folder.
But if I set the mode to 'development', the file will show up.
I want to know why production mode is not working.
Here is my config
const path = require('path');
module.exports = {
devtool: 'none',
entry: './src/index.ts',
mode: 'production',
module: {
rules: [{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}]
},
output: {
filename: 'client.js',
path: path.resolve(__dirname, './build'),
publicPath: path.resolve(__dirname, './build'),
},
resolve: {
extensions: ['.tsx', '.ts', '.jsx', '.js']
},
};
And node code to build file
webpack(config)
.run(function (err, stats) {
console.log(stats.toString({
chunks: false,
colors: true
}));
console.log('Compiled.')
})
Thanks for helping out.

Do I need to add my server.js into my webpack file?

I have a node server with es6 syntax, like import statements, which it cannot recognize. I am pretty sure I would have to add that to my webpack file, but unsure on how to do that and whether it is required. My node server file is called server.js
var webpack = require('webpack');
module.exports = {
entry: {
app: './src/index.js',
vendor: './src/vendor.js'
},
output: {
path: __dirname,
publicPath: '/',
filename: '[name].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor','vendor.js', Infinity)
],
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
}
};
To use the import keyword in Node you have to transpile it so it either has to be processed by webpack if you use it or at least transpiled with a tool like Babel. See this for more info:
https://github.com/babel/babel-preset-env

Resources