Webpack - How to bundle/require all files of a folder (subfolder) - javascript

I am trying to see if there is a shorter way of running webpack bundles, and also why my loaders do not work.
Here is my code:
module.exports = {
context: path.join(__dirname, 'dist'),
entry: ['./ES6bundle.js', './jQuery.js'],
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
}
};
// module: {
// loaders: [{
// test: /\.js?$/,
// exclude: /node_modules/,
// loader: 'babel-loader',
// query: {
// presets: ['env']
// }
// }]
// };
The module.exports works but when I run the loaders I get errors.
My other question is about consolidating multiple entries into one file.
The project I am working on has many JS files, and I was wondering if there was a shortcut for multiple entries. Instead of typing out multiple entries' filenames, can I grab all JS files in the same folder or have a JS file to require them all?
Let me know if this makes sense or not. I am relatively new to programming. Thanks!

Regarding the second part of your question:
can I grab all JS files in the same folder or have a JS file to
require them all
You can have one entry file and in there you do:
module.exports = {
context: path.join(__dirname, 'dist'),
entry: ['./jQuery.js', './allJsFilesOfFolder.js'],
allJsFilesOfFolder.js:
require.context("../scripts/", true, /\.js$/);
This will bundle all scripts inside scripts and all its subfolders.
You need to install #types/webpack-env to have context at your hand.
Specify false if you want to bundle only the scripts in the scripts folder.
You can do the same with other resources like images, you only have to adapt the regex

Copy #Legends comment as answer here.
have no experience with vue files, but as I said you can bundle not only js files, but also image files, for example the regex for image files would be: /.(png|ico|svg|jpg|gif)$/.

Related

how can I bundle multiple libraries with webpack and use them in a browser

Webpack describes a multi-main entry feature that seems to do exactly this, it bundles several libs into one file. The problem is that when I load that file only the last library on the list is available.
I've created a small demo on github.
There are 2 libraries each exporting a single symbol, only lib2.d2 is accessible from the test.html that loads the bundled JS. If you look in the bundle file you can see the code from lib1 but it's not exported in any way that I can find.
The webpack config is below. I suspect the problem is that there's no way to supply 2 library names when there's out only output and so the last one over-writes the earlier ones.
const path = require('path');
module.exports = {
entry: ['./js/lib1.js', './js/lib2.js'],
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
library: {
name: 'MyLibrary',
type: 'umd',
},
filename: 'lib.js',
path: path.resolve(__dirname, 'dist'),
},
"optimization": {
"minimize": false,
usedExports: true,
},
mode: "development",
};
If you're curious why I would want to do this, I'm doing some development on wix.com. The only way to push JS files up to their server is copy/paste one at a time. Bundling a bunch of stuff into one file will save me some pain. My current work-around is to output to multiple files and then cat them all together with something export const exportLib1 = lib1 for each one. That gives me a JS file that I can import and access each one but there must be an easier way.

Are entry points required for non JavaScript assets in web pack 4?

The only way I have successfully had webpack generate a non JavaScript file is to include an entry for the primary asset. The problem is, webpack is generating a .js file based on this asset as well, which is unnecessary. Is this the correct way of working with non JavaScript assets in a webpack config?
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const outputDir = 'build';
const extractStylus = new ExtractTextPlugin('../css/screen.css');
module.exports = {
entry: {
app: './src/js/index.js',
print: './src/js/print.js',
stylus: './src/stylus/screen.styl'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.styl$/,
use: extractStylus.extract({
fallback: 'style-loader',
use: ['css-loader', 'stylus-loader']
})
}
]
},
plugins: [extractStylus],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, `${outputDir}/js`)
}
};
The specific line in question is part of the entry object:
stylus: './src/stylus/screen.styl'
Without that line, nothing is generated, but with that line, the expected .css as well as a stylus.bundle.js file are generated.
I think you misunderstand what the entry property does in a webpack config:
An entry point indicates which module webpack should use to begin building out its internal dependency graph. After entering the entry point, webpack will figure out which other modules and libraries that entry point depends on (directly and indirectly).
Every dependency is then processed and outputted into files called bundles, which we'll discuss more in the next section.
[source, emphasis mine]
Without specifying an entry, webpack would not know where to look for your files; even if the dependency graph was not directional (which it is), you need to point webpack to at least one point of the graph.
The minor problem of having a JS file generated even though you are only processing assets is a consequence of how webpack generally is used – as an asset manager / compiler for some application logic written in JS. So, in theory, if you needed to use the compiled assets via NodeJS style requires, you'd use the generated stylus.bundle.js.

Webpack, new chunk is loading in with wrong path

I am trying to chunk my app - attempting to follow webpacks guide on how-to (https://webpack.github.io/docs/code-splitting.html). So I have a seperate chunk set up for my app, I can see that webpack is generating 1.bundle.js in my build folder, however it is pasting it onto my index.html with an incorrect path, and in my console I see the fetch error for the 1.bundle.js file.
So my webpack config looks like so (im just using the webpack:dev for now):
return {
dev: {
entry: {
index: './client/app.jsx'
},
output: {
path: path.join(__dirname, '..', '..', 'dist', 'client'),
publicPath: "/dist/client/",
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}, {
test: /\.json$/,
loader: 'json-loader'
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
resolveLoader: {
fallback: [path.join(__dirname, 'node_modules')]
},
plugins: [
new webpack.DefinePlugin({
"process.env": {
"NODE_ENV": JSON.stringify("dev")
}
})
]
},
and in my index.html I manually add <script src="bundle.js"></script> and that has been working great. It looks like when this builds now, webpack is applying its own script tag on my index like so
<script type="text/javascript" charset="utf-8" async="" src="/dist/client/1.bundle.js"></script>
However this path is incorrect, it should just be src="1.bundle.js". I have tried tweaking the path and publicPath but nothing seems to work. Is there a way to have webpack add the correct path? Thanks!
You should change publicPath for this snippet:
publicPath: "/"
It will always serve your chunks from root path.
Even though it is answered and accepted, I am providing additional helpful info for others with similar problems.
There are two different purposes for which the 2 parameters are used.
Output:path : The directory the bundle files mentioned in entry section are saved into. For example, the bundle.js for the 'entry' entry you had mentioned. In this case, it will be saved in webconfigfolder+"../../dist/client" folder.
Output: publicPath: The directory prefix that is added to refer to a module when accessed from browser. 0.bundle.js is an unnamed chunk created by code splitting. It will be placed in the output:path mentioned above but will be referred in your html using the public path.
So,if your files as in this case is stored in /dist/client folder, but the index.htm is served in /dist/client, you should give the public path as ./. If htm is served from /dist, the public path should be given as ./client/.
The public path is useful for chunks created for async loading which are called from browser dynamically.
This is because you have given reference to publicPath. So it will try to load the script from this publicPath though the file is not present there.
Removing publicPath can resolve the error

How can I include a global JS file to my React project using webpack?

I'm using React for he first time and I discover that there are some JS functions I need to use accross multiple JSX files.
I've looked at some examples, but can't figure out how to correctly include my global.js file.
My folder structure:
/dist
/src
/components
/sass
/img
index.js
global.js
webpack.config.js
This is my webpack file:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: "./src/index.js",
output: {
path: __dirname + "/js/",
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
cacheDirectory: true,
presets: ['es2015', 'react']
}
}
]
}
};
Can anyone tell me how to correctly include this one file and where in the webpack code this goes?
I am not sure about what you need, but webpack is your building system, so it plays at an lower level from what do you want. If you want to include functions in various file, you need to include the file in wherever you need it:
global.js
module.export = {
func1: ..,
func2: ..
}
file where you need a function:
var globals = require('path/to/global.js')

webpack loaders and include

I'm new to webpack and I'm trying to understand loaders as well as its properties such as test, loader, include etc.
Here is a sample snippet of webpack.config.js that I found in google.
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [
path.resolve(__dirname, 'index.js'),
path.resolve(__dirname, 'config.js'),
path.resolve(__dirname, 'lib'),
path.resolve(__dirname, 'app'),
path.resolve(__dirname, 'src')
],
exclude: [
path.resolve(__dirname, 'test', 'test.build.js')
],
cacheDirectory: true,
query: {
presets: ['es2015']
}
},
]
}
Am I right that test: /.js$/ will be used only for files with extension .js?
The loader: 'babel-loader', is the loader we install using npm
The include: I have many questions on this. Am I right that anything we put inside the array will be transpiled? That means, index.js, config.js, and all *.js files in lib, app and src will be transpiled.
More questions on the include: When files get transpiled, do the *.js files get concatenated into one big file?
I think exclude is self explanatory. It will not get transpiled.
What does query: { presets: ['es2015'] } do?
In webpack config there are multiple things for configuration, important ones are
entry - can be an array or an object defining the entry point for the asset you want to bundle, can be a js as test here says do it only for /.js$. Your application if has multiple entry points use an array.
include - defines the set of path or files where the imported files will be transformed by the loader.
exclude is self explanatory (do not transform file from these places).
output - the final bundle you want to create. if you specify for example
output: {
filename: "[name].bundle.js",
vendor: "react"
}
Then your application js files will be bundled as main.bundle.js and react in a vendor.js files. It is an error if you do not use both in html page.
Hope it helped
This documentation helped me understand better. Looks like it is for webpack 1 but still applies.
https://webpack.github.io/docs/configuration.html#module-loaders
Loaders
An array of automatically applied loaders.
Each item can have these properties:
test: A condition that must be met
exclude: A condition that must not be met
include: An array of paths or files where the imported files will be transformed by the loader
loader: A string of “!” separated loaders
loaders: An array of loaders as string
This example helped me understand what is going on. Looks like you use either include or exclude but not both. The test is a condition applied to all files. So if you include a folder, each file must pass the test condition. I have not verified this, but based on the example provided by the documentation, it look like that is how it works.
module: {
rules: [
{
// "test" is commonly used to match the file extension
test: /\.jsx$/,
// "include" is commonly used to match the directories
include: [
path.resolve(__dirname, "app/src"),
path.resolve(__dirname, "app/test")
],
// "exclude" should be used to exclude exceptions
// try to prefer "include" when possible
// the "loader"
loader: "babel-loader" // or "babel" because webpack adds the '-loader' automatically
}
]
}
1) Correct.
2) Correct.
3) Correct.
4) I am unsure. My webpack.config.js file includes an output key, and does bundle it all into one file:
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js'
}
5) Correct.
6) This tells babel-loader what sort of transpile you want it to perform, as well as other compile options. So, for example, if you want it to transpile jsx as well + cache results for improve performance, you would change it to:
query: {
presets: ['react', 'es2015'],
cacheDirectory: true
}

Categories

Resources