I thought by exporting specific functions and use it will only include this function in a compiled file but it doesn't seem so ex:
file1:
export function redu1(state = null, action) {
return state;
}
export function redu2(state = null, action) {
return state;
}
file2:
import {redu1} from './file1';
What did i see in the compiled file that all the functions are included?
According to Webpack Tree Shaking, you should set property mode to production in your webpack.config.js file to remove dead code from bundle.
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'production'
};
Related
I'm generating a static HTML page with Webpack. I have a custom logging module, and then two other modules which import it. Those imports are in different entry points. The problem is, the logging module is actually being instantiated twice.
sendtolog.js:
'use strict';
import { v4 } from "uuid";
console.log('logging...');
const ssid = v4();
export default function sendToLog(metric) {
console.log(`Sending message with ${ssid}`);
}
webvitals.js:
import { getTTFB } from 'web-vitals/base';
import sendToLog from './sendtolog';
getTTFB(sendToLog);
pageactions.js:
'use strict';
import sendToLog from './sendtolog';
sendToLog({name: 'foo', value: 'bar'});
and then in the browser console:
[Log] logging...
[Log] Sending message with 53f50779-d430-49e1-a1be-5b1bb33db10b
[Log] logging...
[Log] Sending message with 415dd4b9-e089-4feb-a4cf-d29c12a26149
How do I get it to not do that?
The WebPack docs for optimization.runtimeChunk have a giant warning:
Imported modules are initialized for each runtime chunk separately, so
if you include multiple entry points on a page, beware of this
behavior. You will probably want to set it to single or use another
configuration that allows you to only have one runtime instance.
but I'm not using runtimeChunk, I'm just using splitChunks, which I assumed would be "another configuration that allows you to only have one runtime instance."
My WebPack config:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = (env, argv) => {
console.log('Webpack mode: ', argv.mode);
const config = {
entry: {
'main': [
path.resolve(__dirname, './src/pageactions.js'),
],
'inline': [ path.resolve(__dirname,
'./node_modules/web-vitals/dist/polyfill.js'),
path.resolve(__dirname, './src/webvitals.js')
]
},
module: {
rules: [
// JavaScript
{
test: /\.(js)$/,
exclude: /node_modules/,
use: ['babel-loader']
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './views/index.ejs'),
filename: path.resolve(__dirname, 'index.html'),
output: {
path: path.resolve(__dirname, './public'),
filename: '[name].bundle.js'
},
optimization: {
splitChunks: {
chunks: 'all'
},
},
devtool: ('production' === argv.mode) ? false : 'eval',
mode: argv.mode
}
return config;
};
Below are some options from an open-webpack (not CRA) react project:
// webpack.config.js
module.exports = {
// ...
entry: {
main: './src/index.js',
'editor.worker': 'monaco-editor/esm/vs/editor/editor.worker.js',
'yaml.worker': 'monaco-yaml/lib/esm/yaml.worker.js',
},
// ...
How to implement similar configuration in config-overrides.js (using react-app-rewired)?
// config-overrides.js
module.exports = function override (config) {
config.entry = // ???
return config
}
My experience:
Simply set it to:
config.entry = {
main: './src/index.js',
'editor.worker': 'monaco-editor/esm/vs/editor/editor.worker.js',
'yaml.worker': 'monaco-yaml/lib/esm/yaml.worker.js',
}
doesn't work. It even causes issues in loading index.js!
config.optimization.runtimeChunk = 'single'
maybe help you ...
https://webpack.js.org/configuration/optimization/#optimizationruntimechunk
I'm trying to access a function from my (webpack'ed) bundle, but the function is undefined. (The entire object in empty) (In electron-main.js see appBundle.test())
I've been searching all over the web, but can't find the answer I'm looking for.
Tried all the different libraryTarget options, but none of them worked the way I expected.
Here is the source code:
webpack.dev.js:
...
module.exports = Merge(CommonConfig, {
devtool: "inline-source-map",
watch: true,
entry: path.resolve(__dirname, "src/index.ts"),
output: {
filename: "bundle.js",
path: __dirname + "/wwwroot/resources/js/components",
publicPath: "/resources/js/components/",
library: "appBundle",
libraryTarget: "commonjs2"
},
plugins: ([
new webpack.DefinePlugin({
"process.env": {
"NODE_ENV": JSON.stringify("development")
}
}),
// Etract CSS
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
]),
})
index.ts:
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
// Styling
import './application-styling.scss';
// Application
import "./application/index.tsx";
export default function test() {
console.log('hello');
}
electron-main.js:
const { BrowserWindow } = require('electron');
const createAppWindow = require('../main/app-process');
const authService = require('../services/auth-service');
global.window = {}; // <- Need to define this manually, else the require call throws errors
const appBundle = require('app-bundle'); // Trying to import the bundle.js here
let win = null;
function createAuthWindow() {
destroyAuthWin();
win = new BrowserWindow({
width: 1000,
height: 600,
webPreferences: {
nodeIntegration: false,
enableRemoteModule: false
}
});
win.loadURL(authService.getAuthenticationURL());
const { session: { webRequest } } = win.webContents;
const filter = {
urls: [
'http://localhost/callback*'
]
};
webRequest.onBeforeRequest(filter, async ({ url }) => {
console.log(appBundle); // <- undefined or empty object, depending on libraryTarget
console.log(appBundle.test()); // <- error, test is undefined
await authService.loadTokens(url);
createAppWindow();
return destroyAuthWin();
});
...
}
...
Apparently the import "./application/index.tsx"; call somehow messed up the exports. When I just used a clean file as the entry point it worked fine.
Anyway I ended up just building the electron project together with the app bundle into one package.
I have experience in Javascript and jQuery, but I am new to webpack.
I have a file called test1.js:
exports.func1 = function() {
window.alert('hello from func 1');
};
I then have index.js, which contains the following:
import test1 from "./test1"
My webpack.config.js contains:
const path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist'), //folder to put the output file
},
};
I have included app.js into my webpage and that is fine, no errors in console about file cannot be found. I want to call func1() from a button click, for example, <button onclick="func1()">Test</button>.
When I do this I get "func1 is not defined" in console output. Webpack doesn't show any errors when I run it, so it must be the way I am calling the function somehow.
I must be doing something, or not doing something, really stupid. Can someone help as I seem to be going round in circles? Thanks.
It's because test1 is the exported object. func1 is a property of test1.
test1.func1() will invoke the function
You could also import it by destructuring. Try the following:
import { func1 } from './test1'
Change test1.js to:
export default () => {
window.alert('hello from func 1');
};
Then in your index.js:
export { default as test1 } from "./test1"
If you want to consume in HTML you should build a library and update your webpack like below:
const path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist'), //folder to put the output file
library: 'myApp',
libraryTarget: 'umd',
},
};
Now your function is exported and should be available for usage.
I have been working in a project where I need to use the outputPath function from the file-loader, to emit files to different folders, but I had difficulties to understand and making it work.
Part of my code is as follows:
const path = require('path');
const webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const fs = require('fs'); // fs stands for file system, it helps accessing phyisical file systems
const BRANDS = {
br1: 'br1.local',
b22: 'br2.local'
};
module.exports = {
mode: 'production',
entry: {
main: './src/js/main.js'
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]',
outputPath: (url, resourcePath, context) => {
if (/my-custom-image\.png/.test(resourcePath)) {
return `other_output_path/${url}`;
}
if (/images/.test(context)) {
return `image_output_path/${url}`;
}
return `output_path/${url}`;
}
}
},
]
},
documentation says that resourcePath is the absolute path to assets, I am not sure about this, as my assets folder has another name not assets, does it matter? it looks like: /src/images.
What is context not sure what is my context. When I do a console.log of these arguments it shows undefined, and it doesn't emit the images to the right folders.
You just need to add your folder name inside if statement.
If your folder tree looks like this:
/src/images/subfolder/
Change your code to this:
outputPath: (url, resourcePath) => {
if (/subfolder/.test(resourcePath)) {
return `images/subfolder/${url}`;
}
return `images/${url}`;
}