I would like to bundle my chrome extension with Webpack. The source consists multiple entries and the content of the webpack.config.js looks as follows:
const path = require("path");
module.exports = {
entry: {
actions: './src/actions/index.js',
options: './src/options/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, "dist")
}
};
And folder structure:
The actions/index.js and options/index.js files are entries.
My goal is, when the src get bundled then dist folder should looks as follows:
How to configure the webpack config to get the desired folder structure above?
Thanks
This should solve your problems ;)
file structure
src
├── actions
│ ├── index.html
│ └── index.js
└── options
├── index.html
└── index.js
webpack.config.js
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
actions: './src/actions/index.js',
options: './src/options/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name]/index.js'
},
plugins: [
new HtmlWebPackPlugin({
template: './src/actions/index.html',
filename: 'actions/index.html',
chunks: ['actions']
}),
new HtmlWebPackPlugin({
template: './src/options/index.html',
filename: 'options/index.html',
chunks: ['options']
})
]
};
And a more correct version ;)
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const ENTRY = {
actions: './src/actions/index.js',
options: './src/options/index.js'
}
const entryHtmlPlugins = Object.keys(ENTRY).map(entryName => {
return new HtmlWebPackPlugin({
template: `./src/${entryName}/index.html`,
filename: `${entryName}/index.html`,
chunks: [entryName]
});
});
module.exports = {
entry: ENTRY,
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name]/index.js'
},
plugins: entryHtmlPlugins
};
I created a branch on github many-outputs
You can specify the output path for each entry, this will copy the js files into the structure you want.
In order to generate html file for each entry, you can use 2 times HTMLWebpackPlugin with specifying chunk option.
Don't forget to put a src/options.html & src/actions.html html files as a templates.
const path = require('path');
module.exports = {
entry: {
'actions/index': './src/actions/index.js',
'options/index': './src/options/index.js',
},
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'options.html'),
filename: 'options.html',
chunks: ['options'],
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'actions.html'),
filename: 'actions.html',
chunks: ['actions'],
}),
],
};
Related
I am building custom gutenberg blocks using npm, webpack and #wordpress/scripts. Everything was fine until I tried to use block.json file. To use block.json file I need block.asset.php file in the build directory because that's the way WordPress core is coded... (https://github.com/WordPress/gutenberg/issues/40447)
And now my problem is that running npm run build does not generate .asset.php file and I do not know why. When I register blocks using wp_enqueue_script or when I manually create an empty .asset.php it works fine.
My webpack.config.js now looks like this:
const defaultConfig = require("#wordpress/scripts/config/webpack.config");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
module.exports = {
...defaultConfig,
entry: {
'cgbms-section-block': './src/section-block.js',
'cgbms-article-block': './src/article-block.js',
'cgbms-article-header-block': './src/article-header-block.js',
'cgbms-category-block': './src/category-block.js',
'cgbms-category-block-edit': './src/category-block-edit.js',
'cgbms-card-block': './src/card-block.js',
'style-front': './src/css/style-front.scss',
'style-editor': './src/css/style-editor.scss',
},
output: {
path: path.join(__dirname, './build/'),
filename: './blocks/[name].js'
},
module: {
...defaultConfig.module,
rules: [
...defaultConfig.module.rules,
]
},
plugins: [
new MiniCssExtractPlugin({
filename: './css/[name].css'
})
],
externals: {
'#wordpress/blocks': 'wp.blocks',
'#wordpress/block-editor': 'wp.blockEditor'
},
}
Okay so solution is actually really simple.
I think I had to import default plugins config:
...defaultConfig.plugins
So my whole webpack.config.js is now:
const defaultConfig = require("#wordpress/scripts/config/webpack.config");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
module.exports = {
...defaultConfig,
entry: {
'cgbms-section-block': './src/section-block.js',
'cgbms-article-block': './src/article-block.js',
'cgbms-article-header-block': './src/article-header-block.js',
'cgbms-category-block': './src/category-block.js',
'cgbms-category-block-edit': './src/category-block-edit.js',
'cgbms-card-block': './src/card-block.js',
'style-front': './src/css/style-front.scss',
'style-editor': './src/css/style-editor.scss',
},
output: {
path: path.join(__dirname, './build/'),
filename: './blocks/[name].js'
},
module: {
...defaultConfig.module,
rules: [
...defaultConfig.module.rules,
]
},
plugins: [
...defaultConfig.plugins,
new MiniCssExtractPlugin({
filename: './css/[name].css'
})
]
}
as you can see I also removed externals block.
I am trying to bundle my JS files through Webpack (version 5.x) but it is not bundling order-wise. Here is my configuration file:
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "production",
entry: [
"./src/assets/js/plugins/jQuery.js",
"./src/assets/js/plugins/mdb.js",
"./src/assets/js/plugins/aos.js",
"./src/assets/js/main.js",
],
output: {
filename: "assets/js/[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
]
};
I am expecting in the bundle file orderwise like jQuery.js, mdb.js, aos.js and main.js that I added in the entry. Please help me find the issue and a better way to buddle the JS files.
Thank You
I am relatively new with webpack and I was wondering if it is possible to have multiple entries and outputs with the same folder structure but in different directories. Let's suppose I have this structure:
application
views
scripts
docs
file1.js
file2.js
company
cp1.js
cp2.js
and I want to output in this directory/structure:
public
js
build
docs
file1.js
file2.js
company
cp1.js
cp2.js
Actually, my webpack.config.js is like this:
entry: {
app: path.resolve(__dirname, 'application', 'views', 'scripts', 'file1.js'),
app2: path.resolve(__dirname, 'application', 'views', 'scripts', 'file2.js'),
},
output: {
path: path.resolve(__dirname, 'public', 'js', 'scripts'),
filename: '[name].bundle.js'
}
but I do not want to specify individual entries for all js files and it's outputting in the wrong directory. Is it possible?
Here is the sample webpack.config.js code which would generate the required structure.
const glob = require('glob');
const path = require('path');
function getEntries(pattern) {
const entries = {};
glob.sync(pattern).forEach((file) => {
const outputFileKey = file.replace('application/views/scripts/', '');
entries[outputFileKey] = path.join(__dirname, file);
});
return entries;
}
module.exports = {
entry: getEntries('application/**/*.js'),
output: {
path: __dirname + '/public/js/build',
filename: '[name]',
},
module: {
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
],
},
resolve: {
extensions: ['.js'],
},
};
Recently, I managed to use ejs-loader with Webpack 4. But, I started to get trouble with the script tag that webpack create into index.html when it launch : <script type="text/javascript" src="main.js"></script>. His src is not right because if we look my build I need src="/dist/main.js" :
node_modules/
dist/
index.html
main.js
publics/
src/
views/
server.js
package.json
webpack.config.js
What I need to add into my webpack.congfig.js to create a src like I want ?
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'source-map',
module: {
rules: [{
test: /\.ejs$/,
use: ['ejs-loader']
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './views/pages/index.ejs'})
]
}
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'source-map',
output: {
publicPath: '/dist/' // <---- this
},
module: {
rules: [{
test: /\.ejs$/,
use: ['ejs-loader']
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './views/pages/index.ejs'})
]
}
The webpack-dev-server is bundling the html, scss and js files successfully and the output is also getting served on localhost:8080 but the dist folder is not getting created on local. Following is my webpack configuration:
var extractPlugin = new ExtractTextPlugin({
filename: 'main.css'
});
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
devtool: 'inline-source-map',
devServer: {
port: 3000
},
plugins: [
extractPlugin,
new HtmlWebpackPlugin({
template: 'public/index.html'
}),
new CleanWebpackPlugin(['dist'])
]
};
The webpack-dev-server serves the created bundle from memory and does not write it to the dist directory.