I have been trying to use Webpack for several days.
And I encountered a problem in configuring.
This is my configuration now!(webpack config)
// Look for .html files
let htmlFiles = [];
let directories = ["src"];
while (directories.length > 0) {
let directory = directories.pop();
let dirContents = fs
.readdirSync(directory)
.map((file) => path.join(directory, file));
htmlFiles.push(...dirContents.filter((file) => file.endsWith(".html")));
directories.push(
...dirContents.filter((file) => fs.statSync(file).isDirectory())
);
}
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./dist"),
filename: "[name].[contenthash].js",
},
plugins: [
new CleanWebpackPlugin(),
new WebpackBar(),
new HtmlWebpackPlugin({
template: "./src/index.html",
hash: true,
filename: "index.html",
inject: "head",
scriptLoading: "defer",
xhtml: true,
}),
],
module: {
rules: [
//-------> CSS <-------//
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
generator: {
filename: "assets/styles/[name].[contenthash] [ext]",
},
},
//-------> HTML <-------//
{
test: /\.html$/i,
loader: "html-loader",
},
//-------> Images <-------//
{
test: /\.(png|jpe?g|gif)$/i,
type: "asset/resource",
generator: {
filename: "assets/images/[name].[hash][ext]",
},
},
//-------> Fonts <-------//
{
test: /\.(woff(2)?|ttf|eot)$/,
type: "asset/resource",
generator: {
filename: "./assets/fonts/[name].[contenthash][ext]",
But during construction, I see that two files are created from index.js...why??...how to disable it??
How fix it?
Thanks
Two created .js
Related
I want the server reload the page automatic when I update the html file but I keep getting error.
[webpack-dev-middleware] HookWebpackError: Path variable [id] not implemented in this context: [id].[fullhash].hot-update.js
I am not sure if I set the dev-server correctly or the plugin I use make this error.
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
},
mode: "development",
devtool: "source-map",
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.html$/,
use: ["html-loader"],
},
],
},
plugins: [
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
title: "Bootstrap 2",
template: "src/index.html",
filename: "index.html",
}),
],
optimization: {
chunkIds: false,
},
devServer: {
port: 9000,
historyApiFallback: true,
hot: true,
static: path.resolve(__dirname,"dist")
},
};
To create my page i use webpack. In page i want show multiple image. On internet i found library "lightbox2". This library is used for click image and popup. The library have simple example like this:
<a
class="example-image-link"
href="../image/bed-small.jpg" -- not work
href="./469cccac29babd05add3a0b2d23abf0d.jpg" -- work
data-lightbox="example-1"
><img class="example-image" src="../image/bed-small.jpg" alt="image-1" --here work
/></a>
Img src work great and i see picture on my page. When i click on image popup work but image never loaded. I used dev-tools and i see that my image is download with that name '469cccac29babd05add3a0b2d23abf0d.jpg'. So i copy and i see my image. My question is how generate that file name dynamic in my html file ? Below i add my webpack.conf
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
entry: {
main: './js/index.js',
fontAwesome: './js/fontAwe.js',
fontSolid: './js/fontSolid.js',
fontRegular: './js/fontRegular.js',
galery: './js/galery.js',
},
plugins: [
new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
new HtmlWebpackPlugin({
title: 'none',
template: './index.html',
inject: true,
chunks: ['main', 'fontAwesome', 'fontSolid', 'fontRegular'],
filename: 'index.html',
}),
new HtmlWebpackPlugin({
title: 'none',
template: './pages/galeria.html',
inject: true,
chunks: ['galery'],
filename: 'galeria.html',
}),
],
output: {
publicPath: '/',
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
},
},
},
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
// Prefer `dart-sass`
implementation: require('sass'),
},
},
],
},
{
test: /\.html$/i,
loader: 'html-loader',
},
{
//IMAGE LOADER
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/',
},
},
],
},
],
},
};
My dev-tool
No longer current. I found solution. Import image to js file and changed href ;)
change name of photo and use:<div class=""><a src="></a>
I'm generating multiples *.html files in the dist folder of my project (copied with file-loader). The import of styles.css (generated from scss files from my src folder) is present in the generated index.html but not in the other generated html files which are located in my src/pages (and also generated in the dist folder).
How can I add the styles.css import in all generated html files or even better in all targeted html files?
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin'); // to minify JS
module.exports = {
entry: ['#babel/polyfill', './src/js/index.js'],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/bundle.js'
},
devServer: {
contentBase: './dist'
},
optimization: {
//https://webpack.js.org/plugins/mini-css-extract-plugin/
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
comments: /#license/i,
},
},
extractComments: false,
}),
new OptimizeCSSAssetsPlugin({})
], // utilisés pour minifier le css généré en Production
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.s[ac]ss$/i,
chunks: 'all',
enforce: true,
},
},
},
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: false
}
}),
new MiniCssExtractPlugin({
filename: '[name].css'
}),
new CopyPlugin([
{ from: './src/assets/images', to: 'assets/images' },
//{ from: 'other', to: 'public' },
]),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.(html)$/i,
loader: 'html-loader',
options: {
attributes: false,
interpolate: true,
},
},
{
test: /\.s[ac]ss$/i,
use: [
{loader: MiniCssExtractPlugin.loader},
//'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
'postcss-loader',
'sass-loader',
],
},
{
test: /\.svg/,
use: {
loader: 'svg-url-loader',
options: {}
}
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'assets/images',
esModule: false,
}
}
]
},
{
test: /\.html$/,
loader: 'file-loader',
options: {
name: '[name].[ext]'
},
exclude: [
path.resolve(__dirname, 'src/index.html'),
path.resolve(__dirname, 'src/fragments')
]
},
]
}
};
Thank in advance for your help.
For some reason my webpack configuration is loading the images that comes from my SCSS files but not the ones that come from the HTML files. Also when I run the BUILD command in order to deliver my prod archives it does not create the "img" folder. To be honest I'm pretty new with webpack 4 and I guess there's a couple of steps that I'm not including on the WP config file.
This is my webpack.dev.js
This is the prod folder structure that I would want to create:
dist
|----img
|----css
|----js
a.html
b.html
c.html
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
entry: {
main: "./src/js/scripts.js"
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "js/[name].[hash].js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.scss$/,
use: [
"style-loader",
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader"
]
},
{
test: /\.(png|jpg|gif)$/,
use: ["url-loader"]
}
]
},
devServer: {
port: 8080
},
plugins: [
new CleanWebpackPlugin("dist", {}),
new MiniCssExtractPlugin({
filename: "css/style.[contenthash].css"
}),
new HtmlWebpackPlugin({
template: "./src/index.html",
inject: false,
hash: true,
filename: "index.html"
}),
new HtmlWebpackPlugin({
template: "./src/actualitat.html",
inject: false,
hash: true,
filename: "actualitat.html"
}),
new HtmlWebpackPlugin({
template: "./src/projectes.html",
inject: false,
hash: true,
filename: "projectes.html"
})
]
};
This is the way im loading both css and js on my html files:
<link
rel="stylesheet"
href="<%=htmlWebpackPlugin.files.chunks.main.css %>"
/>
<script src="<%= htmlWebpackPlugin.files.chunks.main.entry %>"></script>
I have a "scripts.js" js file where I import the files like this:
import "../scss/style.scss";
import "../img/searchBar-icon.png";
import "../img/townHall.png";
import "../img/icon-title.png";
UPDATE:
I have change the way im loading images using the "file-loader" loader:
{
test: /\.(png|jpg|gif)$/,
use: {
loader: "file-loader",
options: {
outputPath: "img/",
name: "[name][hash].[ext]"
}
}
}
Now all of my images are being copied to the "img" folder which is good, problem is that all the names of the files have hashes now (which make sense since I'm telling the loader to add them) and they're not loading on my html files.
Can you try the following for loading the images?
{
test: /\.(jpe?g|png|gif|ico)$/i,
use: ["file-loader?name=[name].[hash].[ext]"]
}
I use this template It works well. As you can see on the screen, all lybrarys (like bootstrap) render their CSS into vendor.css, but my component renders it into html directly, just into the header part in the html file in tag. Can you tell me how to configure it right?
// webpack.config.js
var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
var nodeExternals = require('webpack-node-externals');
var merge = require('webpack-merge');
var allFilenamesExceptJavaScript = /\.(?!js(\?|$))([^.]+(\?|$))/;
//var ExtractTextPlugin = require('extract-text-webpack-plugin');
// Configuration in common to both client-side and server-side bundles
var sharedConfig = {
resolve: { extensions: ['', '.js', '.ts'] },
output: {
filename: '[name].js',
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
loaders: [
{ test: /\.ts$/, include: /ClientApp/, loader: 'ts', query: { silent: true } },
{ test: /\.html$/, loader: 'raw' },
{ test: /\.css$/, loader: 'to-string!css' },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url', query: { limit: 25000 } },
{ test: /\.(jpg1)$/, loader: 'file?name=[name].[ext]' }
]
}
};
// Configuration for client-side bundle suitable for running in browsers
var clientBundleConfig = merge(sharedConfig, {
entry: { 'main-client': './ClientApp/boot-client.ts' },
output: { path: path.join(__dirname, './wwwroot/dist') },
devtool: isDevBuild ? 'inline-source-map' : null,
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [] : [
// Plugins that apply in production builds only
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
])
});
// Configuration for server-side (prerendering) bundle suitable for running in Node
var serverBundleConfig = merge(sharedConfig, {
entry: { 'main-server': './ClientApp/boot-server.ts' },
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, './ClientApp/dist')
},
target: 'node',
devtool: 'inline-source-map',
externals: [nodeExternals({ whitelist: [allFilenamesExceptJavaScript] })] // Don't bundle .js files from node_modules
});
module.exports = [clientBundleConfig, serverBundleConfig];
and
// webpack.config.vendor.js
var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractCSS = new ExtractTextPlugin('vendor.css');
module.exports = {
resolve: {
extensions: ['', '.js']
},
module: {
loaders: [
{ test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, loader: 'url-loader?limit=100000' },
{ test: /\.css(\?|$)/, loader: extractCSS.extract(['css']) }
]
},
entry: {
vendor: [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'#angular/platform-server',
'angular2-universal',
'angular2-universal-polyfills',
'bootstrap',
'bootstrap/dist/css/bootstrap.css',
'es6-shim',
'es6-promise',
'jquery',
'zone.js',
'angular2-modal'
]
},
output: {
path: path.join(__dirname, 'wwwroot', 'dist'),
filename: '[name].js',
library: '[name]_[hash]',
},
plugins: [
extractCSS,
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.DllPlugin({
path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
name: '[name]_[hash]'
})
].concat(isDevBuild ? [] : [
new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } })
])
};
It seems like you are using style-loader to load your component css. You can change it to be the same loader (most likely file-loader) as the vendor.css in your webpack.config
If you compare the two css loaders in your config files, you can see that webpack.config.vendor.js has this line:
{ test: /\.css(\?|$)/, loader: extractCSS.extract(['css']) }
under loaders. That is the line that takes the CSS and puts it in its own file. So if you change the CSS loader for your webpack.config.js and make sure to add:
var extractCSS = new ExtractTextPlugin('styles.css'); // or name it whatever you want
at the top of the file. It should work.