I have webpack in my plain HTML, CSS, and Javascript application. I use webpack to convert scss to CSS. I want my javascript to be the same untouched in my dist folder, as I want to edit it later my wordpress projects. Webpack is adding a lot of code, which makes the JS files hard to edit later. Here is my config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { HotModuleReplacementPlugin } = require("webpack");
const HtmlWebpackPartialsPlugin = require("html-webpack-partials-plugin");
module.exports = {
mode: "development",
entry: {
index: "./src/js/index.js",
about: "./src/js/about.js",
courses: "./src/js/courses.js",
contactUs: "./src/js/contact-us.js",
},
output: {
filename: "js/[name].bundle.js",
path: path.resolve(__dirname, "dist"),
assetModuleFilename: "images/[name][ext]",
},
devServer: {
static: { directory: path.join(__dirname, "dist") },
port: 9000,
hot: true,
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css",
}),
new HtmlWebpackPlugin({
title: "Leads",
filename: "index.html",
template: "./src/pages/index.html",
chunks: ["index"],
}),
new HtmlWebpackPlugin({
title: "Leads About",
filename: "about-us.html",
template: "./src/pages/about-us.html",
chunks: ["about"],
}),
new HtmlWebpackPlugin({
title: "Courses",
filename: "courses.html",
template: "./src/pages/courses.html",
chunks: ["courses"],
}),
new HtmlWebpackPlugin({
title: "Contact Us",
filename: "contact-us.html",
template: "./src/pages/contact-us.html",
chunks: ["contactUs"],
}),
new HtmlWebpackPartialsPlugin({
path: path.join(__dirname, "./src/partials/footer.html"),
location: "partialfooter",
template_filename: [
"index.html",
"about-us.html",
"courses.html",
"contact-us.html",
],
}),
new HtmlWebpackPartialsPlugin({
path: path.join(
__dirname,
"./src/partials/components/infrastructure.html"
),
location: "infrastructure",
template_filename: [
"index.html",
"about-us.html",
"courses.html",
"contact-us.html",
],
}),
new HotModuleReplacementPlugin(),
],
module: {
rules: [
{
test: /\.js$/,
exclude: "/node_modules",
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"],
},
},
},
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
// Creates `style` nodes from JS strings
// "style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader",
],
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: "asset/resource",
},
],
},
optimization: {
minimize: false,
},
};
How can I get webpack to convert my sass files, but simply copy my JS files?
Perhaps you could use copy-webpack-plugin https://webpack.js.org/plugins/copy-webpack-plugin/ to copy files from your src static folder to your build destination folder. Roughly like this -
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: "source", to: "dest" },
{ from: "other", to: "public" },
],
}),
],
};
The code that Webpack adds can allow many features for JavaScript like transpiling ES6 JavaScript to ES5, bundling, code-splitting and dynamic imports. But if you don't need them a straight copy might do.
I'm working on a multipage application, and I'm trying to make improvements on the bundle process. I already managed to upgrade to Webpack 5 and improve the dev experience, but the big issue that I simply cannot solve is that I cannot serve CSS per page, and not a gigantic CSS file, see here the coverage on DevTools
I have tried splitChunks, but I think that's not related. I also cannot use html-critical-webpack-plugin, or anything that needs changes on the DevOps/Back-End side (currently it does not work). I know it sounds like I didn't search correctly, but I tried a lot, from the docs to a Udemy course, but probably I'm focusing on the wrong problem. My webpack config for production is as follows:
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const paths = require('./paths.js');
module.exports = merge(common, {
mode: 'production',
devtool: false,
output: {
filename: 'js/[name].[contenthash].bundle.js',
path: paths.build,
publicPath: '/',
assetModuleFilename: '[name][ext]',
clean: true
},
module: {
rules: [
{
test: /\.(s?css|sass)$/i,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: false,
modules: false,
},
},
'sass-loader',
],
},
]
},
plugins: [
new ImageMinimizerPlugin({
minimizerOptions: {
// Lossless optimization with custom option
// Feel free to experiment with options for better result for you
plugins: [
['jpegtran', { progressive: true }],
['optipng', { optimizationLevel: 5 }],
// Svgo configuration here https://github.com/svg/svgo#configuration
[
'svgo',
{
plugins: [
'preset-default',
{
name: 'removeViewBox',
active: false,
},
{
name: 'addAttributesToSVGElement',
params: {
attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }],
},
},
],
},
],
],
},
}),
new MiniCssExtractPlugin({
filename: 'styles/[name].[contenthash].css'
}),
new CompressionPlugin({
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
}),
],
optimization: {
minimize: true,
minimizer: [new CssMinimizerPlugin(), '...'],
splitChunks: {
chunks: 'all',
},
},
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000,
},
});
And the common:
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: {
index: [
'./src/scripts/components/slick-slider.js',
'./src/scripts/components/card-slider.js',
'./src/scripts/components/video.js',
'./src/scripts/components/nova-home.js',
'./src/scripts/components/accordion.js',
],
shared: [
'./src/scripts/components/header-menu.js',
'./src/scripts/components/home.js',
'./src/scripts/util/modernizer-webpdetect',
'./src/scripts/components/slide-cards',
'./src/scripts/components/accordion',
'./src/scripts/components/top-banner',
'./src/scripts/components/appLinks'
],
simule: [
'./src/scripts/components/simulate.js',
'./src/scripts/components/feed.js',
'./src/scripts/components/dropdown.js'
],
ouvidoria: [
'./src/scripts/components/ouvidoria-form.js',
'./src/scripts/components/maks.js'
],
tesouroDireto: [
'./src/scripts/components/simulate.js',
'./src/scripts/components/video.js',
'./src/scripts/components/dropdown.js'
],
cbdELc: [
'./src/scripts/components/simulate.js',
'./src/scripts/components/video.js',
],
coe: [
'./src/scripts/components/video.js'
],
lciELca: [
'./src/scripts/components/simulate.js',
'./src/scripts/components/video.js'
],
fundosDeIndices: [
'./src/scripts/components/section-portfolio'
],
fundosImobiliarios: [
'./src/scripts/components/section-portfolio'
],
investimentos: [
'./src/scripts/components/swipe-view.js',
],
precos: [
'./src/scripts/components/feed.js',
'./src/scripts/components/precos.js'
],
ofertasPublicas: [
'./src/scripts/components/public-offers.js'
],
acoes: [
'./src/scripts/components/section-portfolio'
],
bdr: [
'./src/scripts/components/section-portfolio'
],
carteira: [
'./src/scripts/components/section-portfolio'
],
fundosInvestimentos: [
'./src/scripts/components/funds-list.js'
],
comeceInvestir: [
'./src/scripts/components/comece-investir.js',
'./src/scripts/components/slick-slider.js',
'./src/scripts/components/card-slider.js',
'./src/scripts/components/section-portfolio'
],
bolsaValores: [
'./src/scripts/components/section-portfolio'
],
comparadorFundos: [
'./src/comparadorFundos.js'
],
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
},
{
test: /\.pug$/,
use: [
{
loader: 'html-loader',
options: {
attrs: ['img:src', 'source:srcset']
}
},
{
loader: 'pug-html-loader',
}
]
},
{
test: /\.(?:ico|gif|png|jpg|jpeg|webp|webm|mp4|pdf)$/i,
exclude: /node_modules/,
type: 'asset/resource',
},
{
test: /\.(woff(2)?|eot|ttf|otf|svg)$/,
type: 'asset/inline',
},
]
},
plugins: [
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: './src/img/*',
to: './'
},
{
from: './src/video/*',
to: './'
},
{
from: './src/sitemap.xml',
to: './'
},
{
from: './src/robots.txt',
to: './'
}
]
}),
new HtmlWebpackPlugin({
template: './src/index.pug',
filename: './index.html',
chunks: ['index', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/sobre-nos.pug',
filename: './sobre-nos.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/seguranca.pug',
filename: './dicas-de-seguranca-para-investir.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/primeiros-passos.pug',
filename: './investir-para-iniciantes.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/simule.pug',
filename: './simulador-de-investimentos.html',
chunks: ['simule', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/ouvidoria.pug',
filename: './ouvidoria.html',
chunks: ['ouvidoria', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/tributacao.pug',
filename: './tributacao-de-renda-fixa.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-tesouro-direto.pug',
filename: './investir-tesouro-direto.html',
chunks: ['tesouroDireto', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-cdb-e-lc.pug',
filename: './investir-cdb-e-lc.html',
chunks: ['cbdELc', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-coe.pug',
filename: './investir-coe.html',
chunks: ['coe', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-cri-e-cra.pug',
filename: './investir-cri-e-cra.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-debentures.pug',
filename: './investir-debentures.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/pagina-404.pug',
filename: './404.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-lci-e-lca.pug',
filename: './investir-lci-e-lca.html',
chunks: ['lciELca', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-titulos-publicos.pug',
filename: './titulos-publicos.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-ofertas-publicas.pug',
filename: './ofertas-publicas.html',
chunks: ['ofertasPublicas', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-fundos-de-investimentos.pug',
filename: './investir-fundos-de-investimentos.html',
chunks: ['fundosInvestimentos', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-acoes.pug',
filename: './investir-acoes.html',
chunks: ['acoes', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/carteira-investimento-recomendada.pug',
filename: './investir-carteira-recomendada.html',
chunks: ['carteira', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/trader.pug',
filename: './investir-trader.html',
chunks: ['trader', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-fundos-de-indices.pug',
filename: './investir-etf.html',
chunks: ['fundosDeIndices', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/plataformas-trader.pug',
filename: './plataformas-investir-trader.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-fundos-imobiliarios.pug',
filename: './investir-fii-fundos-imobiliarios.html',
chunks: ['fundosImobiliarios', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-mercado-de-opcoes.pug',
filename: './investir-mercado-de-opcoes.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-mini-ibovespa.pug',
filename: './investir-mini-indice.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-mini-dolar.pug',
filename: './investir-mini-dolar.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/alavancagem-day-trade-bovespa.pug',
filename: './investir-day-trade.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/bdr-investir-exterior.pug',
filename: './investir-bdr.html',
chunks: ['bdr', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-contrato-indice.pug',
filename: './investir-contrato-indice-bovespa.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-fundos-de-indices.pug',
filename: './produto-fundos-de-indices.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-contrato-dolar.pug',
filename: './investir-contrato-dolar.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/renda-variavel.pug',
filename: './investir-renda-variavel.html',
chunks: ['rendaVariavel', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/mercado-futuro.pug',
filename: './investir-mercado-futuro.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/produto-letra-financeira.pug',
filename: './investir-letra-financeira.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/investimentos.pug',
filename: './investimentos.html',
chunks: ['investimentos', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/precos.pug',
filename: './taxas-e-precos.html',
chunks: ['precos', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/tributacao-variavel.pug',
filename: './tributacao-de-renda-variavel.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/politica-de-privacidade.pug',
filename: './politica-de-privacidade.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/termos-de-uso.pug',
filename: './termos-de-uso.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/regulamentacao.pug',
filename: './regulamentacao.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/nossos-resultados.pug',
filename: './resultados.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/gestao-de-recursos.pug',
filename: './gestao-de-recursos.html',
chunks: ['shared']
}),
new HtmlWebpackPlugin({
template: './src/comece-a-investir.pug',
filename: './comecar-a-investir.html',
chunks: ['comeceInvestir', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/bolsa-de-valores.pug',
filename: './investir-bolsa-de-valores.html',
chunks: ['bolsaValores', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/comparador-fundos.pug',
filename: './investir-comparador-fundos.html',
chunks: ['comparadorFundos', 'shared']
}),
new HtmlWebpackPlugin({
template: './src/politica-seguranca-informacao.pug',
filename: './politica-de-seguranca-da-informacao.html',
chunks: ['shared']
})
],
resolve: {
alias: {
components: path.resolve(__dirname, '../src/components/'),
data: path.resolve(__dirname, '../src/data/'),
fonts: path.resolve(__dirname, '../src/fonts/'),
img: path.resolve(__dirname, '../src/img/'),
scripts: path.resolve(__dirname, '../src/scripts/'),
statics: path.resolve(__dirname, '../src/statics/'),
styles: path.resolve(__dirname, '../src/styles/'),
video: path.resolve(__dirname, '../src/video/')
}
}
}
The project has a lot of .sass files, to each component/page. These are imported into a main.sass, which is imported in the home.js, in the shared entry point. I suspect this is the problem, but maybe someone could help me?
You can use multiple HtmlWebpackPlugin plugins to create more than one HTML file in production, but only one of the HTML files will be used by the DevServer. Is there any way to use all the HtmlWebpackPlugin plugins in development as well?
module.exports = {
entry: {
main: './src/main.js',
anotherEntry: './src/anotherEntry.js'
},
// This only serves the index.html file on 404 responses
devServer: {
contentBase: './dist',
historyApiFallback: true,
port: 3000,
},
// ...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/main.html',
chunks: ['main'],
}),
new HtmlWebpackPlugin({
filename: 'anotherEntry.html',
template: './src/anotherEntry.html',
chunks: ['anotherEntry'],
}),
]
};
historyApiFallback can be given manual rewrites to control in a more fine-grained manner what the DevServer should fallback to on 404 responses. This way we can serve the other files in development as well.
module.exports = {
entry: {
main: './src/main.js',
anotherEntry: './src/anotherEntry.js'
},
devServer: {
contentBase: './dist',
historyApiFallback: {
rewrites: [
{ from: /^\/anotherEntry/, to: '/anotherEntry.html' },
{ to: '/index.html' },
],
},
port: 3000,
},
// ...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/main.html',
chunks: ['main'],
}),
new HtmlWebpackPlugin({
filename: 'anotherEntry.html',
template: './src/anotherEntry.html',
chunks: ['anotherEntry'],
}),
]
};
I have one react project but I split to two part(admin,front). I want to serv this two part different port via one webpack devserver.
It is possible when I run "npm run start" , two part working at different ports
I built with webpack , outputs in dist directory here
admin.html
index.html
admin.js
index.js
common.js
If I open localhost:8081 -> must return index.html(includes index.js and common.js)
If I open localhost:8082 -> must return admin.html(includes admin.js,common.js)
webpack configuration :
entry: options.production ? {
interview: ["./app/src/pages/interview/main.js"],
admin: ["./app/src/pages/dashboard/main.js"]
} : {
interview: [
'webpack-dev-server/client?http://' + options.ip + ':8081',
"./app/src/pages/interview/main.js",
'webpack/hot/only-dev-server'],
admin: ['webpack-dev-server/client?http://' + options.ip + ':8082',
'webpack/hot/only-dev-server',
"./app/src/pages/dashboard/main.js"]
},
output: {
path: options.production ? './dist' : './build',
publicPath: options.production ? '' : 'http://' + options.ip + ':8081/',
filename: options.production ? '[name].app.[hash].min.js' : '[name].app.js',
},
plugins: options.production ? [
//new DashboardPlugin(),
// Important to keep React file size down
new CommonsChunkPlugin("commons.chunk.js"),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production'),
},
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
beautify: false,
comments: false,
compress: {
warnings: false,
},
mangle: {
// Don't mangle $
except: ['$', '_', '*', '$super', 'exports', 'require'],
// Don't care about IE8
screw_ie8: true,
// Don't mangle function names
keep_fnames: true
}
}),
//new ExtractTextPlugin('app.[hash].css'),
new HtmlWebpackPlugin({
template: './conf/tmpl.html',
production: true,
filename: "index.html",
excludeChunks: ['admin']
}),
new HtmlWebpackPlugin({
template: './conf/tmpl.html',
production: true,
filename: "admin.html",
excludeChunks: ['interview']
}),
new webpack.DefinePlugin({ //export all environment variables
//todo check that if this is really working
'process.env': {
DENEME: JSON.stringify("mesut"),
APPCONFIG: JSON.stringify(confParams)
}
})
] : [
new CommonsChunkPlugin("commons.chunk.js"),
new HtmlWebpackPlugin({
template: './conf/tmpl.html',
filename: "index.html",
excludeChunks: ['admin']
}),
new HtmlWebpackPlugin({
template: './conf/tmpl.html',
filename: "admin.html",
excludeChunks: ['interview']
}),
new webpack.DefinePlugin({ //export all environment variables
//todo check that if this is really working
'process.env': {
DENEME: JSON.stringify("mesut"),
APPCONFIG: JSON.stringify(confParams)
}
})
],