I'm making a chrome extension that hosts multiple applications (multiple devtools panels), each one independent. I need webpack to watch multiple entry points and produce multiple bundles, I don't need common chunks. I definitely do not want to use amd in the client side code like this.
/appOne
index.js
/components
/blah
/foobar
/appTwo
index.js
/components
..etc
/appThree
index.js
/components
..etc.
/chrome <- basically the "dist" folder
/appOne
index.html
bundle.js
/appTwo
index.html
bundle.js
/appThree
etc...
As per docs on multiple entries I've been doing:
{
entry: {
appOne: './appOne/index.js',
appTwo: './appTwo/index.js'
},
output: {
path: path.join(__dirname, 'chrome', '[name]'),
filename: 'bundle.js' //can be the same since they should be output in different folders
}
}
I get the error:
Path variable [name] not implemented in this context: C:\Users\Admin\projects\crx\chrome\[name]
So I guess you cannot have the [name] variable in the path setting for multiple entries?
You should use [name] in the filename field instead of path. Looking at the docs, filename lists the [name] variable and path does not (only showing [hash]).
You would use something like:
{
path: path.join(__dirname, 'chrome'),
filename: '[name]/bundle.js'
}
The documentation does not explicitly state the filename can have multiple path segments, it only says the filename must not be an absolute path.
Related
I'm trying to use the compilation hash for asset/resource file names but no matter what I try it just generates a different hash for every file in the asset/resource output. The chunk file names all get the same and correct compilation hash.
For example, the main bundle files are all correct:
appbundle.42cf6539b0e35868deab.js
polyfillsbundle.42cf6539b0e35868deab.js
etc..
However, the images in the assets folder look like this, with different hashes. Is there a way to get them to match the compilation hash like the bundle chunks?
image1.ec620b3ff0d269c77f1b.svg
image2.984ca5bc273b4992cb6c.svg
etc..
Relevant webpack config:
output:
{
filename: '[name].[hash][ext]',
chunkFilename: '[name].[hash][ext]',
publicPath: './dist/',
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: 'assets/[name].[hash][ext]'
}
...
module: {
rules:
[
...
{
test: /\.(eot|woff|woff2|ttf|png|jpg|gif|svg|ico)$/,
type: 'asset/resource'
},
...
]
}
But what are you trying to achieve?
You are getting a new hash per image file, because with asset/resource you asked Webpack to emit resources to separate files.
When you use [hash] placeholder, Webpack would generate a hash out of the filename. Since you have different filenames ~> different hashes.
If you want to add some random suffix per build to your resources, I'd do something like:
const seed = new Date().getTime() // or your generation strategy
module.exports = {
. . .
output:
{
. . .
assetModuleFilename: `assets/[name].${seed}[ext]`
}
...
guys!! I'm trying to learn webpack and optimize my webpack project(a mutil-page project) configuration, but I got confused in some problems.hope someone can help me.
By the way,please forgive me for not having a good English, but I think Google Translate should basically be able to let me explain my problem. If there is something unclear in the description, please point it out and I will modify it.
Related Links
https://github.com/webpack/webpack/blob/main/examples/multiple-entry-points/webpack.config.js
https://github.com/webpack/webpack/blob/main/examples/multi-compiler/webpack.config.js
Q1.What are the advantages and disadvantages of each in mutil-html page config?
maybe multi-compiler have more flexible configuration but speed slower?
Q2.If I use the configuration of mutil-entry-point, how can I get the current entry name in the plugin or loader?
I know that the author of webpack said that this can't be done on the loader,
https://github.com/webpack/webpack/issues/6124#issuecomment-351647892
but how about in plugin?
Q3.Is there any way to get the entire dependency graph from the entry?
like webpack-bundle-analyzer?
The MultiCompiler allows you to create different rulesets and use different plugins for different files where the multi-target just allows you to compile multiple files and outputs. As for your questions:
Basically yes, multi-compiler does not run in parallel and needs to load the configuration, plugins and rulesets for each compilation. So it is more flexible, but runs slower, there are however alternatives to run it in parallel like parallel-webpack
You can create a custom plugin for your webpack and use their compiler-hooks to get what you want, more specifically I would check out the asset-emitted hook, that looks as follows:
compiler.hooks.assetEmitted.tap(
'MyPlugin',
(file, { content, source, outputPath, compilation, targetPath }) => {
console.log(content); // <Buffer 66 6f 6f 62 61 72>
}
);
If you wish to create your own plugin, this guide of theirs is essential: webpack writing-a-plugin
The best I can come up with is this from webpack-bundle-analyzer npm package :
When opened, the report displays all of the Webpack chunks for your project. It's possible to filter to a more specific list of chunks by using the sidebar or the chunk context menu.
Sidebar
The Sidebar Menu can be opened by clicking the > button at the top left of the report. You can select or deselect chunks to display under the "Show chunks" heading there.
Chunk Context Menu
The Chunk Context Menu can be opened by right-clicking or Ctrl-clicking on a specific chunk in the report. It provides the following options:
Hide chunk: Hides the selected chunk
Hide all other chunks: Hides all chunks besides the selected one
Show all chunks: Un-hides any hidden chunks, returning the report to its initial, unfiltered view
They clarify it in their documentation:
MultiCompiler:
The MultiCompiler module allows webpack to run multiple configurations in separate compilers. If the options parameter in the webpack's NodeJS api is an array of options, webpack applies separate compilers and calls the callback after all compilers have been executed.
var webpack = require('webpack');
webpack([
{ entry: './index1.js', output: { filename: 'bundle1.js' }, ruleset1, pluginsA},
{ entry: './index2.js', output: { filename: 'bundle2.js' }, ruleset2, pluginsB }
], (err, stats) => { // [Stats Object](#stats-object)
process.stdout.write(stats.toString() + '\n');
})
Multiple-entrypoints
If your configuration creates more than a single "chunk" (as with multiple entry points or when using plugins like CommonsChunkPlugin), you should use substitutions to ensure that each file has a unique name.
module.exports = {
entry: {
app: './src/app.js', // Will export to app.js
search: './src/search.js', // Will export to search.js
},
output: {
filename: '[name].js',
path: __dirname + '/dist',
},
};
Also, check out webpack-code splitting
I was studying some code to understand webpack and what it does and came across this code;
const path = require('path');
const docsBuild = {
entry: {
'app/docs/lib/dice-roller': './app/src/main.js'
},
output: {
path: path.join(_dirname,''),
filename: '[name].js'
}
};
module.exports = [docsBuild];
I can't understand why in place of the property of entry main, there is a file path and why the second parameter of path.join is empty. I'm new to webpack and I couldn't seem to find my answer in its documentation, maybe I didn't search well but help would be appreciated.
According to the webpack documentation:
entry:
The point or points to enter the application. At this point the
application starts executing. If an array is passed all items will be
executed.
So the piece of code:
entry: {
'app/docs/lib/dice-roller': './app/src/main.js'
}
Is setting the entry point for 'app/docs/lib/dice-roller' to './app/src/main.js'
output.path:
The output directory as an absolute path.
The second parameter of path.join is the output directory name itself. In your example is empty but, as you can see in the example provided here, for the below project structure:
webpack-demo
|- package.json
|- webpack.config.js
|- /dist
|- /src
You may set this output configuration where __dirname returns the the directory name of the current module:
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
}
Also this 'options' documentation has a paragraph which may clarify this a little bit:
Notice that throughout the configuration we use Node's built-in path
module and prefix it with the __dirname global. This prevents file
path issues between operating systems and allows relative paths to
work as expected. See this section for more info on POSIX vs. Windows
paths.
Hope this helps you.
I'm trying to create a bundle for the intl polyfill to load it only for browser which requires it.
Using the following code, it creates the bundle in my output folder
if (!window.Intl) {
require.ensure(['intl/dist/Intl'], (require) => {
window.Intl = require('intl/dist/Intl');
}, 'intl-bundle');
}
The first thing I noticed is the size of the file is huge, it contains all the languages, is there a way to define the languages I want?
The other issue is that when the browser tries to download the file, it tries from the root folder of my app. So instead of downloading http://mydomain/js/1.intl-bundle.js, it tries to get http://mydomain/1.intl-bundle.js
Is there a way to set from where the file should be downloaded?
My webpack.config.js output looks like this:
output: {
path: './js/',
filename: '[name].js'
},
And the last question, can I remove the 1. at the beginning of the name of the file, just to have intl-bundle.js?
Thanks
I'm actually going to answer a few of my own question as I just found some of the solution after a few hours of research.
For the second question, I wasn't defining the publicPath in my build, which was the reason why the browser was downloading the file from the root of my domain. More info: https://github.com/webpack/docs/wiki/configuration#outputpublicpath
output: {
path: './js/',
publicPath: './js/'
}
For the last question, you can name your chunks with the following:
output: {
chunkFilename: '[id]-[name]-[chunkhash].js'
}
This allows you to decide the name of your chunks.
I still don't have any answer to reduce the size of the intl file.
I have a directory app/server/views/ wherein all the jade files are present. As my application is now beginning to have more jade files, I thought of structuring app/server/views/ based on category of actors for simplicity & maintainence. Something like:
app/server/views/admin/task1.jade
app/server/views/admin/task2.jade
app/server/views/superadmin/task1.jade
app/server/views/superadmin/task2.jade
app/server/views/user/task1.jade
app/server/views/user/task2.jade
If all the jade files are present inside /app/server/views/ directory, my index.js file has no problem in loading the jade files. However on structuring per above mentioned directory format, I run into issues:
server.views({
engines:
{
jade: require('jade')
},
path: [ __dirname + "/app/server/views/admin", __dirname + "/app/server/views/superadmin", __dirname + "/app/server/views/user" ]
});
With the above index file, my jade files won't load.
I don't think path can be an array. From the docs, I gather that it should be one directory.
Something like path: Path.join( __dirname, 'app/server/views' ) then call the templates from your controller as reply( 'admin/task1', ....).
If you can determine your actor's role programatically and have exactly the same code, then something like reply( actorsRole + '/task1' ) should do the trick.