Webpack 4: Copying pictures and fonts - javascript

I create a project with the following structure:
Webpack 4 configuration:
const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
output: {
path: __dirname + '/web'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader']
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: __dirname + '/fonts'
}
}]
},
{
test: /\.(jpg|png)$/,
use: {
loader: "file-loader",
options: {
name(file) {
if (env === 'development') {
return './images/[name].[ext]'
}
return '[hash].[ext]'
}
}
}
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html'
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
};
After compilation, the main.js, main.css and index.html are placed in the web folder. How to make all the pictures in the project copied to the web/images, and the fonts in the web/fonts?
In the project, I refer to them as follows:
1) src\Interface\Header\Index.js
<img src="img/logo.png" srcSet="img/logo#2x.png 2x, img/logo#3x.png 3x" className="header-logo" alt=""/>
2) src\Pages\App\style.css
#font-face {
font-family: 'HelveticaNeueCyr';
src: url('/fonts/HelveticaNeueCyr.woff2') format('woff2'),
url('/fonts/HelveticaNeueCyr.woff') format('woff');
font-weight: normal;
font-style: normal;
}

module.exports = {
output: {
path: __dirname + '/web'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader']
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts'
}
}]
},
{
test: /\.(jpg|png)$/,
use: {
loader: "file-loader",
options: {
name: 'images/[name].[ext]',
outputPath: 'images'
}
}
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
filename: './index.html'
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
};

Related

Webpack 5.47.1 : Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema

I am using React Application. Below is my Webpack Configuration file for 5.47.1.
const path = require('path');
const webpack = require('webpack');
process.noDeprecation = true;
module.exports = (options) => ({
entry: options.entry,
output: Object.assign({ // Compile into js/build.js
path: path.resolve(process.cwd(), 'build'),
publicPath: '/',
}, options.output), // Merge with env dependent settings
module: {
mode: 'development',
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.css$/,
include: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(eot|svg|otf|ttf|woff|woff2)$/,
use: 'file-loader',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
progressive: true,
optimizationLevel: 7,
interlaced: false,
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.json$/,
use: 'json-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
plugins: options.plugins.concat([
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV' : JSON.stringify('development'),
}),
// new webpack.NamedModulesPlugin(),
]),
resolve: {
modules: ['app', 'node_modules'],
extensions: [
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
performance: options.performance || {},
});
I have updated mode. Could not figure out the config issues here
mode should be in the root object and not in the module object:
module.exports = (options) => ({
mode: 'development',
entry: options.entry,
output: Object.assign({ // Compile into js/build.js
path: path.resolve(process.cwd(), 'build'),
publicPath: '/',
}, options.output), // Merge with env dependent settings
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.css$/,
exclude: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.css$/,
include: /node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(eot|svg|otf|ttf|woff|woff2)$/,
use: 'file-loader',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
progressive: true,
optimizationLevel: 7,
interlaced: false,
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.json$/,
use: 'json-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
plugins: options.plugins.concat([
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
}),
// new webpack.NamedModulesPlugin(),
]),
resolve: {
modules: ['app', 'node_modules'],
extensions: [
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
performance: options.performance || {},
});

document is not defined after running webpack scripts

So I tried creating a boilerplate for an existing project that our company have and after running the script for webpack,
it generated a ./dist/server.js however, when I run it from node, I am getting this document not found error. Please let me know if you need a code snippet of a specific file.
ERROR
){var n=(0,r.renderToString)(o().createElement(Wn,null));a.send('\n <!DOCTYPE html>\n <html>\n <head>\n </head>\n <body style="margin:0">\n <div id="root">'+n+'</div>\n </body>\n <script src="main.bundle.js" defer><\/script>\n </html>\n')})),Hn.listen(3e3,(function(){console.log("app listening on port 3000!")}))})()})();
ReferenceError: document is not defined
code above is a long one line code which I had to cut off
webpack.config.client.js
const path = require('path');
module.exports = {
mode: 'production',
entry: {
main: './src/index.tsx',
},
module: {
rules: [
{
loader: 'ts-loader',
test: /\.(tsx|ts)?$/,
exclude: [/node_modules/],
},
{
test: /\.(scss)$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
options: {
name: '/src/assets/images/[name].[ext]'
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: "file-loader"
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].bundle.js',
sourceMapFilename: '[file].map',
path: path.resolve(__dirname, 'dist/public'),
},
};
webpack.config.server.js
const path = require('path');
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const nodeExternals = require('webpack-node-externals');
const { join } = require('lodash');
module.exports = {
mode: 'production',
entry: {
server: './server/index.tsx',
},
target: 'node',
node: {
__dirname: false,
__filename: false,
},
externals: [nodeExternals()],
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
title: "Test",
template: './src/index.html'
})
],
module: {
rules: [
{
loader: 'ts-loader',
test: /\.tsx?$/,
options: {
transpileOnly: true,
},
exclude: [/node_modules/],
},
{
test: /\.(s*)css$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
options: {
name: '/src/assets/images/[name].[ext]'
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: "file-loader"
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
};

Webpack is not bundling css from node_modules

I'm migrating a react website to webpack 4 (from 3) but have been running into some strange problems when using webpack for css.
It works fine for the css that I wrote myself, but any css from third party components in node_modules does not seem to be included at all.
Here is an example of my webpack config:
const webpack = require('webpack');
const path = require('path');
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const config = {
entry: [
'react-hot-loader/patch',
'./src/index.js'
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
exclude: [/node_modules/, /global\.css$/],
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
}
},
'postcss-loader'
]
},
{
test: /\.css$/,
include: [/node_modules/, /global\.css$/],
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 0,
modules: true,
}
}
]
},
{
test: /\.png$/,
use: [
{
loader: 'url-loader',
options: {
mimetype: 'image/png'
}
}
]
},
{
test: /\.svg$/,
use: 'file-loader'
},
{
test: /\.jpg$/,
use: [
{
loader: 'url-loader',
options: {
mimetype: 'image/jpg'
}
}
]
},
]
},
resolve: {
extensions: [
'.js',
'.jsx'
],
alias: {
'react-dom': '#hot-loader/react-dom'
},
modules: [
'node_modules',
],
},
devServer: {
contentBase: './dist'
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
new LodashModuleReplacementPlugin,
new HtmlWebpackPlugin({
template: require('html-webpack-template'),
inject: false,
appMountId: 'app',
})
],
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
module.exports = (env, argv) => {
if (argv.hot) {
// Cannot use 'contenthash' when hot reloading is enabled.
config.output.filename = '[name].[hash].js';
}
return config;
};
Only css from my own files are included in the generated bundle.
I'm using the latest versions:
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"
Greatful for any help!
Layout of the project

Webpack, extract-loader doesn't load load background url

I'm having trouble with extract-loader. I try to add background: url(../../assets/icons/upload.svg); to sass, but I get an error.
Error: Cannot find module '../../assets/icons/upload.svg' from '/home/jeremy/code/sample-project/src/styles'
Tried resolve-url-loader, but without success.
My webpack config:
module: {
rules: [
{
test: /\.(js)$/,
exclude: /node_modules/,
loader: require.resolve('babel-loader'),
},
{
test: /\.(png|svg|jpg|gif)$/,
include: [
path.resolve(__dirname, 'src/assets/'),
],
use: [
'file-loader'
],
},
{
test: /\.hbs$/,
loader: require.resolve('handlebars-loader'),
query: {
inlineRequires: '/assets/',
},
},
{
test: /\.scss$/,
use: [
{
loader: require.resolve('file-loader'),
options: {
name: 'main.css',
}
},
require.resolve('extract-loader'),
require.resolve('css-loader'),
require.resolve('postcss-loader'),
require.resolve('sass-loader'),
],
}
]
},

webpack only compile files with recent changes

I am working on a large codebase; I have multiple src files to compile. When I run watch or compile for production it will compile all files found in src. Which is exactly what webpack should do.
But I would like to compile only the files which have been recently changed instead of all the files. Is this possible?
Here's my webpack config
const path = require("path");
const webpack = require("webpack");
const extractTextPlugin = require("extract-text-webpack-plugin");
const {VueLoaderPlugin} = require("vue-loader");
module.exports = {
entry: {
clients:
"./src/clients/Resources/vue-js/clients.js",
dashboard:
"./src/dashboard/Resources/vue-js/dashboard.js",
mapView:
"./src/mapView/Resources/vue-js/mapView.js",
admin:
"./src/admin/Resources/vue-js/admin.js"
},
output: {
path: path.join(__dirname, "./dist/"),
publicPath: "/dist/",
filename: "js/[name].js",
chunkFilename: "js/[name].js"
},
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: "vendor",
filename: "js/vue_bundle.js",
automaticNameDelimiter: "_",
test: /[\\/]node_modules[\\/]/,
chunks: "all",
priority: 1,
minChunks: 2,
minSize: 0
},
}
},
occurrenceOrder: true,
},
module: {
rules: [
{
test: /\.vue$/,
loader: "vue-loader"
},
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/,
options: {
presets: ["env"]
}
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: "url-loader?limit=100000"
},
{
test: /\.css$/,
use: extractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.scss$/,
use: extractTextPlugin.extract({
// use: ['raw-loader', 'sass-loader']
use: "raw-loader!sass-loader"
})
},
{
test: /\.sass$/,
use: extractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader!sass-loader"
})
},
{
test: /\.jpe?g$|\.ico$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$|\.wav$|\.mp3$/,
loader: "file-loader?name=[name].[ext]"
},
{
test: /\.yaml$/,
loader: "json-loader!yaml-loader"
}
]
},
plugins: [
new extractTextPlugin({
filename: "css/[name].css",
allChunks: true
})
]
};

Categories