file-loader creating extra file in root of dist folder - javascript

I am using file loader 6.2 to copy static image files into an images folder in my dist destination and it all works fine using the following config (ie the svg is copied from my src folder to the dist/images):
test: /\.(png|jpe?g|gif|svg)$/i,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images',
publicPath: 'images',
},
However, as well as the static file being copied over, it also creates another file in the root of the dist folder that references the static - eg, when I copy a file called loading.svg, it creates that file as well as a file with a random hash (eg 817e56ed349aea52edfa.svg)
and inside this file, it just references the other file:
export default "images/loading.svg";
If I then check my compiled sass, I can see it references the hash file instead of the asset that was copied into the images folder.
background: url(../817e56ed349aea52edfa.svg) center center no-repeat;
How do I stop the extra file being created so that it only creates and references the image in the images folder directly?
On a side note, I tried swapping file loader for copy webpack plugin, and that also copied the files into the images folder, but on that occasion, instead of referencing that file, it just also created a hash version of the svg (but with the actual svg contents rather than a webpack export) in the root directory and referenced that instead - so it may be something else causing this issue? I include full webpack config below in case anyone can spot anything obvious or something else is causing the issue
Full webpack config
const paths = require("./webpack.paths");
const { VueLoaderPlugin } = require('vue-loader');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require("terser-webpack-plugin");
const isProduction = (process.env.NODE_ENV === 'production');
if (isProduction) {
console.log("Bundling in PRODUCTION mode")
} else {
console.log("Bundling in DEVELOPMENT mode")
}
module.exports = {
entry: {
styles: paths.styles,
home: './vue/templates/home/main.js',
},
mode: isProduction ? 'production' : 'development',
output: {
path: paths.dist,
filename: 'js/[name].js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.(css|scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
// Use the css-loader to parse and minify CSS imports.
loader: 'css-loader',
options: { sourceMap: true }
},
{
// Use the postcss-loader to add vendor prefixes via autoprefixer.
loader: 'postcss-loader',
options: {
postcssOptions: {
config: paths.postcssConfig,
},
sourceMap: true
}
},
{
// Use the sass-loader to parse and minify CSS imports.
loader: 'sass-loader',
options: { sourceMap: true }
},
],
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images',
publicPath: 'images',
},
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['#babel/preset-env', { targets: "defaults" }],
]
}
},
},
]
},
devServer: {
hot: true,
noInfo: true,
overlay: true,
contentBase: [paths.root],
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: 'css/[name].css'
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [
`${paths.dist}/css/*`,
`${paths.dist}/images/*`,
`${paths.dist}/js/*`,
],
}),
new ESLintPlugin({
extensions: ['vue', 'js'],
})
],
optimization: {
minimize: isProduction,
minimizer: [
new TerserPlugin(),
],
runtimeChunk: 'single',
splitChunks: {
minSize: 0,
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'all',
test: /[\\/]node_modules[\\/]/,
priority: 10,
enforce: true
}
}
}
}
}
if (isProduction) {
module.exports.plugins = (module.exports.plugins || []).concat([
new CompressionWebpackPlugin(),
])
}

In the end it looks as if it was the css loader that was causing the issue - so I configured it to ignore urls and then changed from the file-loader plugin to the copy-webpack-plugin to copy the images:
Ignore urls with css loader
MiniCssExtractPlugin.loader,
{
// Use the css-loader to parse and minify CSS imports.
loader: 'css-loader',
options: {
sourceMap: true,
url: false,
}
},
Copy webpack plugin to copy images
const CopyPlugin = require("copy-webpack-plugin");
plugins: [
new CopyPlugin({
patterns: [
{
from: 'vue/images', // src location
to: 'images', // destination location in dist folder
},
],
options: {
concurrency: 100,
},
}),
]
Then in my css I could just reference the image as relative from the dist folders css to the dist folder images folders:
background-image: url(../images/loading.svg);
Seems a bit odd to me that I had to do it this way in order not to get the extra svg file so if anyone comes up with a better solution or knows how not to create the extra file, please feel free to answer

Related

Webpack loads wrong images to dist directory

My webpack.config.js file
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: {
index: './src/js/index.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true },
},
],
},
{
test: /\.(jpg|png)$/,
use: {
loader: 'url-loader',
},
},
{
test: /\.(css|scss)$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
},
],
},
output: {
path: path.resolve(__dirname, './dist'),
filename: './js/[name].bundle.js',
},
plugins: [
new HtmlWebPackPlugin({
template: path.resolve(__dirname, './src/index.html'),
filename: 'index.html',
chunks: ['index'],
}),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: './css/[name].css',
}),
new CopyWebpackPlugin({
patterns: [{ from: './src/assets', to: './assets' }],
}),
],
devtool: 'source-map',
mode: 'development',
};
my files structure where the problem occurs:
what is strange, when I run npm run build in the terminal, all directories are loaded correctly I mean: background-image works, and slider directory with images is loaded, but there is also loaded some additional files with random numerical names
and those three additional .png files are loaded to my index.html as img1.png img2.png and img3.png files which not work on my website, they just do not want to load
This is caused by Webpack 5's new Asset Modules. You can either remove url-loader and specify the asset type like so:
{
test: /\.(jpg|png)$/,
type: 'asset/inline',
},
Or you can disable asset modules by adding type: 'javascript/auto' to your rule:
{
test: /\.(jpg|png)$/,
use: {
loader: 'url-loader',
},
type: 'javascript/auto'
}
See the documentation to learn more, and to see how to do this for file-loader and raw-loader as well.
I think your image files are probably double-processed, because you once just copy your assets folder to your dist output folder, and then you somewhere probably use the images with url("./someImage") or similar in your css files, which get processed by your css loader or css Mini Exctract plugin, which creates that cryptic image asset output, that then gets used in your html files, look at here: webpack.js.org/guides/asset-management/#loading-images.. I dont know why you need to copy your assets folder but that looks redundant to me...
EDIT: I'm not an expert at this, but after investigating some hours into this weird error, I realized that the paths were set correctly to the image files, but the image output that file-loader or other loaders generate with the image (like 0f9b8be78d378ad2ef78.jpg) seems to be something different, if I open them in vscode editor in standard text/binary editor, I get this line: export default __webpack_public_path__ + "someimage.jpg";, with url-loader its the binary64 converted string with data-url(..).. so it seems its not for the purpose to use it in static html files..
I then used the recommended way to do it like this in webpack.config.js:
{ test: /\.(jpg|png)$/,
type: 'asset/resource', }
after that my image was shown correctly, I have no idea what file-loader etc. is doing..
here is my final webpack.config.js:
const path = require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
entry: {
index: './src/js/index.js',
},
devServer: {
port: 5757,
contentBase: path.resolve(__dirname, 'src'),
publicPath: '/src',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: { minimize: true },
},
],
},
{
test: /\.(jpg|png)$/,
type: 'asset/resource',
},
{
test: /\.(css|scss)$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
},
],
},
output: {
path: path.resolve(__dirname, './build'),
//publicPath: './assets/images',
},
plugins: [
new HtmlWebPackPlugin({
template: path.resolve(__dirname, './src/index.html'),
filename: 'index.html',
inject: 'body',
}),
new MiniCssExtractPlugin({
filename: './css/[name].css',
}),
],
devtool: 'source-map',
mode: 'development',
}
I have just solved my every problem because after using the answer from #ChillaBee, images were working correctly expect my background photo which I used in css file as url. Use the answer above but change
{
test: /\.(jpg|png)$/,
type: 'asset/resource',
},
to
{
test: /\.(jpg|png)$/,
type: 'asset/inline',
},
now images from html and css are loaded correctly

How to set image links for a multipage webpack configuration when the landing page is not in a subdirectory?

I am trying my hand at a multipage webpack configuration and have a question about how to load images differently for a landing page compared to the other pages on the site. The landing page builds to the root directory, while the other pages build to their respective subfolders.
Webpack appends the correct relative path ../images/ for the other pages, however the landing page needs to remain as images/, as it is located on the root directory along with the images folder.
How can I configure webpack such that <img src="images/00.jpg"> stays the same for the landing page, but is updated to <img src="../images/00.jpg"> for all other pages?
Here is the source folder:
/ src /
-home.html
-about.html
js/
-home.js
-about.js
images/
-00.jpg
-01.jpg
scss/
-style.scss
Here is the build folder webpack generates:
/ public_html /
-index.html // relative links in this file become broken :(
-bundle.js
about/
-index.html
-bundle.js
images/
-00.jpg
-01.jpg
css/
-style.css
Finally, here is the webpack configuration. Please excuse the wall of code, I decided to include the entire configuration in case there is a better way to set this up.
// webpack.config.js
const webpack = require('webpack');
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: {
home: './src/js/home.js',
about: './src/js/about.js',
},
output: {
filename: (pathData) => {
return pathData.chunk.name === 'home' ? 'bundle.js' : '[name]/bundle.js';
},
path: path.resolve(__dirname, 'public_html')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
},{
test: /\.sass$|\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader' },
{ loader: 'sass-loader' },
],
},{
test: /\.(jpg|png|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath:'images/',
publicPath:'../images/' // how to exclude home.html ?
}
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
hash: true,
filename: 'index.html', // landing page remains in root directory
template: 'src/index.html',
chunks: ['home']
}),
new HtmlWebPackPlugin({
hash: true,
filename: 'about/index.html', // all other pages move to subdirectories
template: 'src/about.html',
chunks: ['about']
}),
new MiniCssExtractPlugin({
filename: "css/style.css"
}),
new CleanWebpackPlugin()
]
};
Thank you! And also, let me know how you like this configuration file!
I have it working. horray!
I never ended up using publicPath. Maybe there would have been a way to change it, but this ended up being a red herring. Instead I restructured my src directory to follow the pattern I was looking for, and removed html-loader so the paths wouldn't get changed during the build process.
Here is my new source directory:
/ src /
-home.html
templates/
-about.html
js/
-home.js
-about.js
images/
-00.jpg
-01.jpg
scss/
-style.scss
You can see home.html is purposely on the main directory rather than in /templates. Image sources are referenced as images/ in home.html, and ../images/ elsewhere.
Now instead of html-loader, I used copy-webpack-plugin to require / copy the images from the source directory to the build folder, as html-loader was changing the paths during the build process. It took me a few tries to figure out that html-loader was the culprit.
Here is my final working webpack config for the record.
// webpack.config.js
const webpack = require('webpack');
const path = require('path');
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
context: path.resolve(__dirname, 'src'),
entry: {
home: './js/home.js',
about: './js/about.js',
},
output: {
filename: (pathData) => {
return pathData.chunk.name === 'home' ? 'bundle.js' : '[name]/bundle.js';
},
path: path.resolve(__dirname, 'public_html')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
},{
test: /\.sass$|\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader' },
{ loader: 'sass-loader' },
],
},{
test: /\.(jpg|png|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[path][name].[ext]'
}
}
]
}
]
},
plugins: [
new CopyPlugin({
patterns: [
{from:'./image',to:'image'}
],
}),
new HtmlWebPackPlugin({
hash: true,
filename: 'index.html', // landing page remains in root directory
template: 'index.html',
chunks: ['home']
}),
new HtmlWebPackPlugin({
hash: true,
filename: 'about/index.html', // all other pages move to subdirectories
template: 'templates/about.html',
chunks: ['about']
}),
new MiniCssExtractPlugin({
filename: "style.css"
}),
new CleanWebpackPlugin()
]
};
I solve the problem on this Way.
Import images on views
Import YourImage from '../../public/assets/img/your-image.png';
Call where you need with implement them
src={YourImage}
Or in your classNames
background-image: `url(${YourImage})`
Config the path to your project repository from GitHub in the rules section of webpack.config.js file.
Repository: "https://maikpwwq.github.io/your-repository/"
rules: [ { type: "asset", test: /\.(png|svg|jpg|gif|jpeg)$/i, use: [{ options: { publicPath: '/your-repository/'}, loader: 'file-loader' ]} } ]

Produce sourcemap from compiled SASS in webpack4

My project is not a JS web app. It is a traditional CMS with PHP templates that invoke the needed JS and CSS files. I'm using webpack4 with this goals:
For JS: Bundle, minify, polyfill, and create a js sourcemap --which is working well, no problem here.
Copy assests (fonts and images) from a folder in src. to another in dist. --working too.
For my SCSS files: compile Sass from a given directory, add prefixes, and output a single css file onto an specific folder, including the CSS SOURCEMAP.
Everything is working BUT I cannot generate the CSS sourcemap. I can do all this with Grunt, but I was hoping to only use one tool -webpack!
I'm pasting my config file to see if anyone spots what is wrong.
I already tried adding options:{ sourceMap:true,} to this loaders:
sass-loader, postcss-loader, css-loader
but then I get a long list of errors that seem to emanate from extrac-loader.
I appreciate any hints or help on this issue. I already spent 2 days troubleshooting it without any progress!
const path = require('path');
const OptimizeCSSAssetsPlugin = require(
"optimize-css-assets-webpack-plugin"
); // Recommended for Minifying outputted css
const cssnano = require("cssnano"); // Used by OptimizeCSSAssetsPlugin
var webpack = require('webpack'); // used by SourceMapDevToolPlugin --which was recommended over devtool.
module.exports = {
cache: false,
entry: {
'main': [ // forces webpack to process specified files
'../src/js/main.js',
'../src/sass/screen.scss',
],
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../dist/js'), // watchout: all output paths in 'rules' will be relative to this path
},
mode: 'development',
devtool: false, // passes sourcemap control to SourceMapDevToolPlugin
module:{
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'file-loader',
options: {
name: '../css/[name].css', // Destination of final processed css file
}
},
{
loader: 'extract-loader', //The extract-loader evaluates the given source code on the fly and returns the result as string.
},
{
loader: 'css-loader?-url', //The css-loader interprets #import and url() like import/require() and will resolve them.
},
{
loader: 'postcss-loader', // adds prefixes
},
{
loader: 'sass-loader', // Loads a Sass/SCSS file and compiles it to CSS
},
]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets:
[
'#babel/env',
{
// "corejs": 3,
}
]
}
}
},
] // End of rules
}, // End of module
plugins: [
new webpack.SourceMapDevToolPlugin(
{
filename: '[name].map',
columns: false,
module: true,
}
),
new OptimizeCSSAssetsPlugin({
cssProcessor: cssnano,
cssProcessorOptions: {
discardComments: {
removeAll: true,
},
// Run cssnano in safe mode to avoid
// potentially unsafe transformations.
safe: true,
},
canPrint: false,
}),
],
} // End of module.exports
Ok, my approach was wrong. Modified a few things and now I have sourcemaps for js and css files.
I'm pasting my webpack.config file in case someone finds it useful (maybe this is obvious for most, but I'm new to webpack, hopefully this will help another newbie like me).
Changes I did:
I turns out that extract-loader and file-loader were not needed. I used mini-css-extract-plugin instead... which allows for the sourcemaps.
There's a conflict with optimize-css-assets-webpack-plugin (if you are using it for minification), so check the plugin part configuration to make sure your sitemaps are generted.
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // extracts and saves css files
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); // Minifies css
const cssnano = require("cssnano"); // Used by OptimizeCSSAssetsPlugin in the css minification
var webpack = require('webpack'); // used by SourceMapDevToolPlugin
module.exports = {
cache: false,
entry: {
'main': [ // forces webpack to process specified files
'../src/js/main.js',
'../src/sass/main.scss',
],
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../dist/js'), // watchout: all output paths in 'rules' will be relative to this path
},
mode: 'development',
devtool: false, // passes sourcemap control to SourceMapDevToolPlugin
module:{
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets:
[
'#babel/env',
{
// "corejs": 3,
}
]
}
}
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '/public/path/to/',
},
},
{
loader: 'css-loader', //The css-loader interprets #import and url() like import/require() and will resolve them.
options: {
url: false,
sourceMap: true,
},
},
{
loader: 'postcss-loader', // adds prefixes
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader', // Loads a Sass/SCSS file and compiles it to CSS
options: {
sourceMap: true,
// importer: globImporter(),
},
},
]
},
] // End of rules
}, // End of module
plugins: [
new MiniCssExtractPlugin({
filename: '../css/[name].css'
}),
new OptimizeCSSAssetsPlugin({
cssProcessor: cssnano,
cssProcessorOptions: {
map: {
inline: false, // set to false if you want CSS source maps
annotation: true
},
discardComments: {
removeAll: true,
},
// Run cssnano in safe mode to avoid
// potentially unsafe transformations.
safe: true,
},
canPrint: false,
}),
new webpack.SourceMapDevToolPlugin(
{
filename: '[name].map',
columns: false,
module: true,
}
),
],
} // End of module.exports

Large console output produced by mini-css-extract-plugin

Been trying to research this but it doesn't seem as if any else has this, or see this as an issue.
I am using mini-css-extract-plugin(MiniCssExtractPlugin) in my webpack.config.js.
However, when I run webpack the console is littered with hundreds of instances of something similar to this...
Child mini-css-extract-plugin ../../../node_modules/css-loader/index.js??ref--6-1!../../../node_modules/postcss-loader/src/index.js!../../../node_modules/sass-loader/lib/loader.js!ui/radiolist-toggler/RadioListToggler.scss:
Entrypoint mini-css-extract-plugin = *
[../../../node_modules/css-loader/index.js?!../../../node_modules/postcss-loader/src/index.js!../../../node_modules/sass-loader/lib/loader.js!./ui/radiolist-toggler/RadioListToggler.scss] /Users/~~~/git/user-section/node_modules/css-loader??ref--6-1!/Users/~~~/git/user-section/node_modules/postcss-loader/src!/Users/~~/git/user-section/node_modules/sass-loader/lib/loader.js!./ui/radiolist-toggler/RadioListToggler.scss 5.33 KiB {mini-css-extract-plugin} [built]
+ 1 hidden module
I need to scroll up for a good few seconds to be able to see all my assets etc.
I am pretty new to webpack, so not exactly sure how to prevent this from being output to the console?
Below is my webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const modernizr = require("modernizr");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
context: path.resolve(__dirname, 'src/main/client'),
entry: './index',
devtool: 'cheap-module-source-map',
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
mangle: true,
compress: true,
ecma: 6
},
sourceMap: true
}),
new OptimizeCssAssetsPlugin({}),
],
splitChunks: {
chunks: 'all'
}
},
plugins: [
new CompressionPlugin({
test: /\.js$|\.css$|\.html$|\.(png|svg|jpg|gif)$/,
cache: true,
filename: '[path].gz[query]',
algorithm: 'gzip',
threshold: 10240
}),
new CleanWebpackPlugin([
'./target/webapp'
]),
new HtmlWebpackPlugin({
template: './index.html',
filename: '../index.html',
xhtml: true
}),
new MiniCssExtractPlugin({
filename: "[name].css",
}),
new CopyWebpackPlugin([{
from: '../webapp/**/*',
to: '../'
}]),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
],
output: {
publicPath: '/app/',
filename: '[name].bundle.js',
chunkFilename: '[id].js',
path: path.resolve(__dirname, 'target/webapp/app/')
},
module: {
rules: [{
loader: "webpack-modernizr-loader",
test: /\.modernizrrc\.js$/
},
{
test: /\.html$/,
exclude: /node_modules/,
use: {
loader: 'html-loader'
}
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './assets/fonts/'
}
}]
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: ["#babel/env"]
}
}
],
},
resolve: {
alias: {
// You can add comment "Please do not delete this file" in this file
modernizr$: path.resolve(__dirname, "./.modernizrrc.js")
}
}
}
#mcclosa mentioned this as a comment but in case anyone should look at this question, see no answer and click away, the solution is to add the stats option to your webpack.config.js file as follows:
module.exports = {
stats: { children: false },
}
The above option uses the children: false option suggested by #mcclosa, which does successfully remove the junk output by mini-css-extract-plugin, but I find using the preset stats: "minimal" produces a much nicer overall output. Using:
module.exports = {
stats: "minimal",
}
..gives me the following tiny output whenever my build has no errors:
i 「wdm」: Compiling...
i 「wdm」: 69 modules
i 「wdm」: Compiled successfully.
..as opposed to dozens of lines of useless build data, but it will continue to give give error information when errors are present.
Unfortunately, mini-css-extract-loader does not have a setting to control the verbosity of its log output.
Setting stats.children to false or "minimal" in your webpack.config.js can remove a lot of other useful output like your bundle names and sizes, entry point information, time taken to build, legitimate warnings and errors from other plugins that you may want to keep, etc.
Instead it seems that we must add a plugin that executes on the compiler's done hook to remove items from the stats.compilation object associated with mini-css-extract-plugin.
This example plugin should work:
class CleanupMiniCssExtractPlugin {
apply(compiler) {
compiler.hooks.done.tap("CleanupMiniCssExtractPlugin", stats => {
if (this._children) {
const children = stats.compilation.children;
if (Array.isArray(children)) {
stats.compilation.children = children.filter(
child => child.name.indexOf("mini-css-extract-plugin") == -1
);
}
}
});
}
}
Or you can use this npm package: https://www.npmjs.com/package/cleanup-mini-css-extract-plugin

Click to open PDF - You may need an appropriate loader to handle this file type

I'm trying to import a PDF into a .js file in order to have a Click to open pdf into my render.
Importing
import myFile from './assets/files/myfile.pdf';
Rendering
render() {
return (
...
<a href={myFile}>
<span>Click to open PDF</span>
</a>
...
)}
Error
myProject.bundle.js:88481 ./assets/files/myfile.pdf 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
Webpack.config.js
I tried several PDF loader without success, the webpack below uses url-loader.
const path = require('path'),
webpack = require('webpack'),
CleanWebpackPlugin = require('clean-webpack-plugin'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractPlugin = new ExtractTextPlugin({ filename: './assets/css/app.css' });
const config = {
mode: 'production',
// absolute path for project root with the 'src' folder
context: path.resolve(__dirname, 'src'),
entry: ['babel-polyfill', './main.js'],
// entry: {
// // relative path declaration
// app: './main.js'
// },
output: {
// absolute path declaration
path: path.resolve(__dirname, 'dist'),
filename: 'myProject.bundle.js',
publicPath: '/'
},
module: {
rules: [
// ************
// * SEE HERE *
// ************
{ test: /\.pdf$/, use: 'url-loader' },
// babel-loader with 'env' preset
{ test: /\.jsx?$/, include: /src/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ['env', 'es2015', 'react', 'stage-0'] } } },
// html-loader
{ test: /\.html$/, use: ['html-loader'] },
// sass-loader with sourceMap activated
{
test: /\.scss$/,
include: [path.resolve(__dirname, 'src', 'assets', 'scss')],
use: extractPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
],
fallback: 'style-loader'
})
},
// file-loader(for images)
{ test: /\.(jpg|png|gif|svg)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: './assets/images/' } } ] },
// file-loader(for fonts)
{ test: /\.(woff|woff2|eot|ttf|otf)$/, use: ['file-loader'] },
]
},
plugins: [
// cleaning up only 'dist' folder
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
template: 'index.html'
}),
// extract-text-webpack-plugin instance
extractPlugin
],
};
module.exports = config;
Note: I'm testing this on localhost if that makes any difference.
SOLUTION
The problem came from the fact that I wasn't restarting the dev server by running npm run startdev after making some changes.
Include it in the file loader, as you do with images:
{ test: /\.(jpg|png|gif|svg|pdf)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: './assets/images/' } } ] },
Note that I have added |pdf after the SVG declaration. Webpack should then process the file as it does with images.
config.module.rules.push({
test: /\.pdf$/,
use: {
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
},
},
});
// vue.config.js configureWebpack
config.module
.rule('pdf')
.test(/\.pdf$/)
.use('pdf')
.loader('file-loader')
.end();
config.module
.rule('pdf')
.test(/\.pdf$/)
.use('file-loader?name=[path][name].[ext]')
.loader('file-loader')
.end();

Categories