Webpack: how to copy html files into build folder? - javascript

I am working on a JavaScript project that is using Webpack. To be honest, I am a bit new to Webpack. Let me explain how my project's build system work. When I run "npm run dev", it copies the files from js, scss and other folders within the project's root folder into the build folder which is also inside the project's root folder. There is an index.html file inside the project's root folder. The index.html file is copied right into the {root}/build/index.html folder. Now, what I am trying to do is that I am trying to add a new HTML file right under the project root folder called, info.html. When I run "npm run dev", I want it to copy the info.html file into build/index.html folder. I tried putting the following in the webpack.config.dev.js file.
{
test: /\.html$/i,
loader: 'html-loader',
}
But the info.html file is not copied across over into the build folder. How can I do that?
When I used the CopyWebpackPlugin, it was throwing the following error.
node_modules\copy-webpack-plugin\node_modules\p-limit\index.js:30
} catch {}
^
SyntaxError: Unexpected token {
at new Script (vm.js:51:7)
at createScript (vm.js:136:10)
at Object.runInThisContext (vm.js:197:10)
at Module._compile (internal/modules/cjs/

No need of file-loader or html-loader when you are using copy-webpack-plugin.
Import the module in your webpack config:
const CopyPlugin = require('copy-webpack-plugin');
and append this to plugins section:
...
plugins: [
...
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, 'info.html'),
to: path.resolve(__dirname, 'build')
},
],
}),
...
],
...

You need to upgrade nodejs, the version number must be greater than 10.13.0

Related

how to make a file in src at webpack file

when i put "webpack" file in a new folder and extract it in new folder i go to the "src" file and then go to the terminal of "VSCODE" and write "npm install" after that "npm run build" so i can see every things in "src" file that copied in "dist" file , but my question is that : when i create a new folder in "src" and write "npm run build" in vscode , that new folder wont build in "dist" . in "dist" folder there is just "src" files . how can i put new folder that i have made in "src" , at "dist" file . thanks . i made a new folder in "src" and i cant see this file in "dist"
By default, webpack will use index.js file in src/index.js. This may vary depending on the webpack version.
Generally, its preferred to specify the entry files. Based on your question, I'm assuming you are trying to add additional files to webpack entry that would be parsed and build by webpack.
This is handled by defining additional entry in webpack.config.js
https://webpack.js.org/concepts/entry-points/
module.exports = {
...
entry: {
main: './src/index.js',
vendors: './src/vendors.js',
},
...
};
In the example above, webpack will generate two files in dist/.
dist/main.js
dist/vendors.js
Here is the question I am getting from this:
How can I configure my webpack config so that a new file created in a given src folder will be processed and moved to a given dist folder when running npm run build?
Solution:
For a new source file to be recognized by webpack, you will either need to create a new entry in your webpack.config.js or you will need to import some exported function from your new file into an existing entry.
Here is an example scenario:
I have a directory app containing: app/src/, app/dist/, app/webpack.config.js, app/src/index.js
And when I run npm run build, a file called index.bundle.js is generated in me app/dist folder
I now want a new script contact.bundle.js generated in my app/dist folder when I run npm run build
My existing webpack.cofig.js file looks something like this:
module.exports = {
entry: {
index: "./src/index.js",
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist")
},
}
But I want to modify it so now my src/contact.js is recognized by webpack and processed as dist/contact.bundle.js
So I update my webpack.config.js file as follows:
module.exports = {
entry: {
index: "./src/index.js",
contact: "./src/contact.js"
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist")
},
}
Please comment if the answer needs to be clarified any further.

Webpack - Bundle multiple/different versions of .css files

I would like to make my bundled .css file being generated by Webpack more configurable, so I can output different 'versions' - based on the same .css file - to make the life of developers working on my project in the future easier.
I would like to have the following steps:
Concat of all SCSS into CSS (bundle.css)
Minimize output of step 1 (bundle.min.css)
Embed all images from step 2 (bundle.b64.min.css)
Embed all fonts from step 3 (bundle.bs64.fonts.min.css)
In the end - after my build process -, I would have 4 distinct files in my dist folder. Would that me possible?
The way I'm currently doing it, I run a different script for each step - deletes dist folder, goes through project, produces the output. I would like to have a single script that does all of it at once without having to go through my project 4 times.
I kind of found a solution for it here:
Webpack Extract-Text-Plugin Output Multiple CSS Files (Both Minified and Not Minified)
But, for my specific case, I would have to return 4 different configurations in a array instead of a single object.
Ok so based on our comment conversation i'm gonna give you a workflow of steps 1-4, but with regular assets handling, not a bundling of assets (which i haven't heard of but maybe someone else can elaborate there).
So the steps:
bundle all scss files into 1 bundle.css
make sure this bundle is minified
add assets management to build for images
add assets management to build for fonts
The important things:
This workflow is basically a built by configuration. configuring the npm scripts with the package.json file, and configuring webpack with config.webpack.js. This will allow you to simply run 1 command to build your project: npm run build. note: For simplicity's sake i am going to ignore production/development/etc environments and focus on a single environment.
package.json:
This is used to set up the command that will actually run when you input npm run build in the terminal (from the project dir of course).
since we are avoiding different environments for now and as you are not using Typescript this is a very simple configuraton:
"scripts": {
"build": "webpack",
},
that's all you have to add. It sound's stupid now but when the project will get more complex you are going to like those scripts so better start off making them already.
webpack.config.js:
The major lifting will be made in this configuration file. This basically tells webpack what to do when you run it (which is what npm run build is doing).
first off let's install some plugins:
npm install --save-dev file-loader
npm install --save-dev html-webpack-plugin
npm install --save-dev mini-css-extract-plugin
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'production',
devtool: 'source-map'
entry: './client/src/app.jsx',
output: {
path: path.join(__dirname, 'client/dist/public'),
filename: 'bundle.[hash].js'
},
module: {
rules: [
{
test: /\.s?css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: false
}
},
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
},
resolve: {
extensions: ['.js', '.json', '.jsx']
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './client/src/index_template.html'
}),
new MiniCssExtractPlugin({
filename: 'style.[hash].css',
chunkFilename: '[id].[hash].css'
}),
]
};
Notice i've added the htmlWebpackPlugin because it makes it easier to reference the correct hashed bundles automatically. Also I've assumed the app is a react app but you can just change the entry point to where your app loads from.
This is quite hard to do of the fly without testing things out, but i hope this gives you enough reference as to what you should change and do to get going with it.
Again i strognly recommend the webpack.js guides and documentation, they are very thorough and once you start getting the hang of it things start working smoothly.

Webpack is adding extra code to bundled file (resulting it to throw error after include)

I am setting bundling in my node project with webpack. I have created webpack config file to bundle file. but after including bundle file I got an error.
I am trying to bundle jquery file into output path. I am able to bundle It using below webpack.config.js code.
var path = require('path');
module.exports = {
target: 'web',
output: {
path: path.resolve(__dirname, "./public/javascripts"),
filename: "bundle-jquery.js",
},
entry: './bower_components/jquery/dist/jquery.min.js'
}
Now I am including output path which is bundled into script src replacing jquery. But its not working and I am getting "$ not defined error". By viewing bundled file, I found that there is an extra code added at start into bundled file.
You are doing it completely wrong. If you want jquery in your project, you should import it in your code.
Entry should be your main.js or whatever your entry file is called. Then in main.js do:
import $ from 'jquery' // or use relative path
Webpack will then bundle jquery for you.

bundling multiple js files

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.

Make webpack move files from src to dest without processing it

I have some sites running with JSF and some vanilla ES6 that is being processed with webpack (Running 4.6).
The problem is that webpack adds something to my jsf.js file when it moves the file to my dest folder, and doesn't work with how JSF needs to be run.
Setup: There is the jsf.js and the vanilla ES6 files in a src folder. I then use webpack to process and move the bundle and the jsf.js file to a dest folder.
The JSF.js file is already minimized in the src folder and cannot be uglified so I have added exclude on uglify:
optimization: {
minimizer: [
new UglifyJsPlugin({
exclude: /(jsf.js)/,
})
]
}
The jsf.js also has its own entry btw.
So my question is, how do I make webpack only move the jsf.js and add nothing to it? There must be some kind of exclude that I am missing here. I use no plugins other than uglify.
If you just want copy jsf.js to dist directory. you should try copy-webpack-plugin, not give it its own entry.
install it throught npm:
npm i -D copy-webpack-plugin
require it in webpack.config.js
const CopyWebpackPlugin = require('copy-webpack-plugin')
add to plugins's array
[
new CopyWebpackPlugin([
{ from: 'path/to/jsf.js', to: 'dist/' }
])
]

Categories