I'm really new to Webpack 4 and found a configuration issue I can not resolve.
I'm configuring Webpack for a multi page application. HTML template engine is PUG.
Files are compiled correctly, but when I create the bundle, Webpack is also compiling the mixins I have at "src/pug/mixins" folders. Therefore I get an .html file from every .pug mixin file I have.
How can I tell Webpack not to generate an .html file from a mixins located inside a folder?
I have the following at my webpack.config file:
module: {
rules: [
{
test: /\.pug$/,
use: ["pug-loader"],
exclude: [path.resolve(__dirname, 'src/pug/utils')]
},
However, all mixins inside utils folder are converted (i.e: utils/coreMixins.pug -> utils/coreMixins.html )
Thanks for your answers
Related
I'm new to webpack, still a little bit confused that how webpack cooperate with loaders. Let's we have below typescript file index.ts:
//index.ts
import "bootstrap/dist/css/bootstrap.css";
...
// typescript code
and below is the webpack config file:
module.exports = {
mode: "development",
entry: "./src/index.ts",
output: { filename: "bundle.js" },
resolve: { extensions: [".ts", ".js", ".css"] },
module: {
rules: [
{ test: /\.ts/, use: "ts-loader", exclude: /node_modules/ },
{ test: /\.css$/, use: ["style-loader", "css-loader"] }
]
}
};
Below is my personal thought on how webpack works with loaders, please correct me if I'm wrong:
Step 1-Webpack encounter index.ts, so it passes this file to ts-loader, and ts-loader read the file and pass it to ts compiler, ts compiler generates js code file index.js and pass back to ts-loader, then ts-loader passes index.js back to webpack.
Step 2- Webpack reads index.js and needs to resolve the css file, so Webpack passes the task to css-loader, so css-loader reads the css file as a long long string, then passes the task to style-loader, which creates js code that can be embedded in tags in the index.html file.
Step 3- bundle.js is ready, and client sends a http request to get index.html, and the bundle.js is fetched and create a <style> tags to include all css styles.
Is my above understanding correct? If yes, below is my questions:
Q1-after style-loader generates js code, does it pass those js code back to css-loader, then css-loader passes received js code to webpack? or style-loader pass generated js code to webpack directly?
Q2- in the webpack config file:
...
{ test: /\.css$/, use: ["style-loader", "css-loader"] }
...
it seems that the style-loader is used first, then css-loader steps in( I have tried this approach, it worked, not sure why it worked)
isn't that the css-loader should start to work first then style-loader as:
...
{ test: /\.css$/, use: ["css-loader", "style-loader"] }
...
Is my above understanding correct?
Yes
Q1-after style-loader generates js code, does it pass those js code back to css-loader, then css-loader passes received js code to webpack? or style-loader pass generated js code to webpack directly?
Answer: style-loader pass generated js code to webpack directly
Q2 it seems that the style-loader is used first, then css-loader steps in,
It can seem wrong. But its one of those things you need to read the docs for. The last thing to process it is mentioned at the top of the array. Personally I don't think the other way around would be any more intuitive.
in react using webpack every js files is bundle into a single bundle.js , for my normal html , css, js application for example , i am having 6 libraries. for an example consider
i am using jquery and bootstrap min versions. so if i reference two files the request will be two. so how can i make it into a single file. So there will be a single request.
like when i checked the file size is about in kb's and the request is processed within less that 1 or 2 seconds , like the chrome dev tools shows the time for to load also it parrallely loads the two files.
But how can i bundle the two librarys using webpack and get a single file that i can refer in my application.
i am a beginner to webpack
You need to import them in your entry point file and Webpack will handle the bundling. As you have worked with React, I assume you have basic command line skills.
You can read the Getting Started guide which bundles Lodash like how you are trying to bundle jQuery and Bootstrap.
First of install, ensure that you are installing jQuery, Bootstrap, and any other libraries using npm (or yarn, if you prefer):
# Install Webpack as a dev dependency
npm install webpack webpack-cli --save-dev
# Install dependencies (I've added Popper.js as Bootstrap requires it)
npm install jquery bootstrap popper.js
Create a folder called src and a file inside there called index.js. This is your entry point and Webpack will look for this file unless configured differently. Import the libraries like this:
import $ from 'jquery'
import 'bootstrap'
// Do something with jQuery
$(document).ready(() => console.log('Hello world!'))
Then run Webpack using npx:
npx webpack
A file named main.js should be created in a folder called dist that contains the bundled code. This is your output file. You can use a <script> tag in your HTML file to load this JavaScript:
<!-- assuming your index.html is in the dist folder -->
<script src='main.js'></script>
Once you get here, you can explore more advanced things like importing Bootstrap components individually, minifying code, multiple bundles, transpiling TypeScript, etc.
You will likely need to add a Webpack configuration file very soon as there is only so much that can be done using zero-config mode.
Good practice is to keep two sepearate bundles for the application logic and external libraries and in webpack this can be achieved by the following code,
app.js - appliation index file,
vendors.js - import all external libraries in this file
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
To get a single file, import vendors.js file inside app.js file and give entry key in webpack as
entry: './src/app.js'
Let us assume that you have the files in src directory. You can merge multiple files by specifying them in webpack.config.js to have a single named file as an output. I hope this is what you are looking for.
const path = require('path');
module.exports = {
entry: {
'bundle.js': [
path.resolve(__dirname, 'src/file1.js'),
path.resolve(__dirname, 'src/file2.js')
]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [{
exclude: /node_modules/
}]
}
};
As above, the two files "file1.js" and "file2.js" will be combined into a single file "bundle.js" and stored in "dist" directory.
You can also exclude node_modules by specifying a rule in module object of webpack configuration.
I am working with this Angular starter pack, works awesome, would recommend.
https://github.com/preboot/angular-webpack
However in the project I would like to have one global app.scss which contains more _partial.scss files, like most sass projects, then have the components encapsulated scss files inside they're own directory, which also use the globals scss file.
However when I try to import a partial scss file into app.scss I get this error in my browsers console.
./~/css-loader!./~/postcss-loader!./~/sass-loader/lib/loader.js!./src/style/app.scss
Module build failed:
#import 'settings/_color';
^
File to import not found or unreadable: settings/_color.
The files are definitely in the right directory, I just can work out why webpack cannot compile them.
I'm pretty sure it is on this line: 121
{
test: /\.(scss|sass)$/,
exclude: root('src', 'app'),
loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader', 'postcss-loader', 'sass-loader']})
}
can anyone help I can get the app.scss to compile successfully with the partial files?
I've got a vue-js app that uses webpack. Everything works fine in development and test environments, but I'm having trouble getting it to build for production.
I've got background images in the LESS files. The image files are in /static. (I'm not sure whether that's kosher or if they should be in side src/assets.)
At any rate, when the LESS has something like this:
background-url: url("/static/img/foobar/my-image.svg")
Then the compilted CSS will have the same url
background-url: url("/static/img/foobar/my-image.svg")
When the browser loaders, it can't find that imgate file. The browser is attempting to find the file here:
file:///static/img/foobar/my-image.svg
Can anyone recommend a way to prepend the absolute path when the app builds for production?
Do you have your static assets outside of our project directory in /static ?
Otherwise I don't get why your browser is trying to request it from file:///static/img/foobar/my-image.svg
anyway, your static assets should be part of your repo/project. They do not need to be in src directory, a /static folder within the root of your project is just fine.
when you compile your application - let's say into a dist folder - you should copy the images also in that dist folder. In my app I use the copy-webpack-plugin for that task (I have my images in ./public/assets/img/.. and I reference them as /assets/img/..)
const CopyWebpackPlugin = require('copy-webpack-plugin');
...
plugins: [
...
/** copy all files from the public folder to the compilation root */
new CopyWebpackPlugin([{
from: 'public',
to : ''
}]),
...
also you should make sure that you have the file-loader in place for your static assets. I use it like so:
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\??\#?v=[.0-9]+)?$/,
use : 'file-loader?name=assets/[name].[hash].[ext]'
}
I hope this will help you to resolve your problem.
I ended up moving the images into assets/img and then updating my webpack config to specify the directory using publicPath. Here's what it ended up looking like:
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'file-loader',
include: [resolve('src')],
options: {
limit: 10000,
name: '/[name].[hash:7].[ext]',
publicPath: path.resolve(__dirname, 'app')
}
I'm trying to load html partials in to my angular app using ngtempalte-loader I can't figure out how to only include a certain folder.
Lets say my tree structure is as so:
-root/
-webpack.config.js
-app/
-templates/
-template1/
-file.html
-template2/
And I'm using this in the config file for webpack:
{
test: /\.html$/,
loader: 'ngtemplate?prefix=app/templates/!html'
}
I also tried with
relativeTo=
But i have no luck... It always goes through all my app and picks up all the html files. I would like to just have the partials in this folder being dealt with ngtemplate-loader.
You guys know how?
Not sure if this is still relevant, but you can give this a try. You require Node's 'path' module for this.
{
test: /\.html$/,
loader: 'ngtemplate?relativeTo=' + (path.resolve(__dirname, './app/templates')) + '/!html'
}