How to bundle assets folder fully - webpack - javascript

I am building a Web Application using MEAN stack.
I am using webpack to bundle my files.
In my project, I have two folders called 1.public/assets (in this assets folder I have separate folders called CSS, js, etc.. which contains various js and CSS.
and I have a folder called 2.client (in this I have my AngularJs code like controllers.js, services.js)
I am using webpack to bundle my client code.
const path = require('path');
const glob = require('glob');
const CleanWebpackPlugin = require('clean-webpack-plugin');
// const CopyWebpackPlugin = require('copy-webpack-plugin');
const outputDirectory = 'dist';
module.exports = {
mode: 'development',
target: 'web',
entry: {
app: glob.sync('./client/*.js'),
},
output: {
path: path.resolve(__dirname, outputDirectory),
filename: '[name].bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
query: {
presets: ['env', 'stage-0'],
},
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|woff|woff2|eot|ttf|svg|jpg)$/,
loader: 'url-loader?limit=100000',
},
],
},
devServer: {
port: 3005,
open: false,
disableHostCheck: true,
proxy: {
'/': 'http://localhost:8005',
},
},
plugins: [
new CleanWebpackPlugin([outputDirectory]),
// new CopyWebpackPlugin([
// { from: 'public/assets' },
// ]),
],
};
I am just bundling my client folder and compiling that into app.bundle.js,
How to compile assets?
NOTE: I am using AngularJs v1.

Webpack starts from each entry point (you could have more than one entry point) and creates a dependency graph. Files/assets are added to the dependency graph when you have imported them into your application through the use of require and import statements.
What is not clear in your question is the relationship between your client folder and your public/assets folder, and whether they are linked. However, if none of the files in your client folder depend upon (require, import) any of the assets in your public/assets folder then they won't be in webpack's dependency graph, and therefore won't be transpiled and bundled.

Related

Webpack4 how to load images and custom javascript directly from HTML file?

I want to load images directly from HTML with Webpack 4 and add custom Javascript files to my HTML file but both files inspected at console show Not found 404.
How to properly load images and Javascipt files with Webpack 4?
My Webpack 4 config file:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: {
main: "./src/index.js"
},
output: {
path: path.join(__dirname, "../build"),
filename: "[name].bundle.js"
},
mode: "development",
devServer: {
contentBase: path.join(__dirname, "../build"),
compress: true,
port: 3000,
overlay: true
},
devtool: "cheap-module-eval-source-map",
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader" // transpiling our JavaScript files using Babel and webpack
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
"style-loader", // creates style nodes from JS strings
"css-loader", // translates CSS into CommonJS
"postcss-loader", // Loader for webpack to process CSS with PostCSS
"sass-loader" // compiles Sass to CSS, using Node Sass by default
]
},
{
test: /\.(png|svg|jpe?g|gif)$/,
use: [
{
loader: "file-loader", // This will resolves import/require() on a file into a url and emits the file into the output directory.
options: {
name: "[name].[ext]",
outputPath: "assets",
}
},
]
},
{
test: /\.html$/,
use: {
loader: "html-loader",
options: {
attrs: ["img:src", ":data-src"],
minimize: true
}
}
}
]
},
plugins: [
// CleanWebpackPlugin will do some clean up/remove folder before build
// In this case, this plugin will remove 'dist' and 'build' folder before re-build again
new CleanWebpackPlugin(),
// The plugin will generate an HTML5 file for you that includes all your webpack bundles in the body using script tags
new HtmlWebpackPlugin({
template: "./src/index.html",
filename: "index.html"
}),
]
My webpack.prod.js file:
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const TerserJSPlugin = require("terser-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-
plugin");
const BrotliPlugin = require("brotli-webpack-plugin");
const PurgecssPlugin = require('purgecss-webpack-plugin');
const glob = require("glob");
module.exports = {
entry: {
main: "./src/index.js"
},
output: {
path: path.join(__dirname, "../build"),
filename: "[name].[chunkhash:8].bundle.js",
chunkFilename: "[name].[chunkhash:8].chunk.js"
},
mode: "production",
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader" // transpiling our JavaScript files using
Babel and webpack
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader", // translates CSS into CommonJS
"postcss-loader", // Loader for webpack to process CSS with
PostCSS
"sass-loader" // compiles Sass to CSS, using Node Sass by
default
]
},
{
test: /\.(png|svg|jpe?g|gif)$/,
use: [
{
loader: "file-loader", // This will resolves import/require()
on a file into a url and emits the file into the output directory.
options: {
name: "[name].[ext]",
outputPath: "assets/"
}
},
]
},
{
test: /\.html$/,
use: {
loader: "html-loader",
options: {
attrs: ["img:src", ":data-src"],
minimize: true
}
}
}
]
},
optimization: {
minimizer: [new TerserJSPlugin(), new OptimizeCSSAssetsPlugin()],
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all"
}
},
chunks: "all"
},
runtimeChunk: {
name: "runtime"
}
},
plugins: [
// CleanWebpackPlugin will do some clean up/remove folder before build
// In this case, this plugin will remove 'dist' and 'build' folder
before re-build again
new CleanWebpackPlugin(),
// PurgecssPlugin will remove unused CSS
new PurgecssPlugin({
paths: glob.sync(path.resolve(__dirname, '../src/**/*'), { nodir:
true })
}),
// This plugin will extract all css to one file
new MiniCssExtractPlugin({
filename: "[name].[chunkhash:8].bundle.css",
chunkFilename: "[name].[chunkhash:8].chunk.css",
}),
// The plugin will generate an HTML5 file for you that includes all
your webpack bundles in the body using script tags
new HtmlWebpackPlugin({
template: "./src/index.html",
filename: "index.html"
}),
My project nesting:
--Build
--src
----html
----js
----styles
----assets
------images
I want that files would load simply:
<img src="assets/images/myimage.jpg">
<srcipt src="js/custom.js"></script>
Any help would be appreciated.
Ironically this is my second project with Webpack 4 and this time I can't fix this issue, the first time there was no problem.
This is how img work in Webpack:
<img src=require("./assets/images/myimage.jpg")>
if you use "require" with file-loader, you need to add default.
<img src=require("./assets/images/myimage.jpg").default>
For script tag, src should be your output bundle.js file; because Webpack writes all the code into the bundle.js with the help of Babel. So when browser request html, browser will have only one Javascript file which is the bundle to download. That is the whole point of bundle, smaller bundle.js is better for performance.
// According to your Webpack config, it is main.bundle.js
<srcipt src="main.bundle.js"></script>
but in order to browser to use this main.bundle.js, it has to be publicly available. So you need express to define the public folder, when browser looks for main.bundle.js, you app will be looking into the public folder and if that file exists, it will ship it to the browser.
const express = require("express");
const server = express();
const staticMiddleware = express.static("build");
server.use(staticMiddleware);

How to customize webpack build script for React App

I am moving a web app to react, therefore and moving from Grunt as a buildtool over to webpack. Right now, the below code is the webpack.config file. This is set up as recommended for developing and then has a build script (npm run and npm build)
However, the build script now only concatenates the components/react js files and puts them at the root of the dist folder. No other files are copied over. I don't understand the point of the build script if that's all it does. But I need to be able to add that in, however, no resource with reacts build scripts shows how you would go about that
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./app/src/components/app.js",
output: {
path: path.join(__dirname, "/dist"),
filename: "index_bundle.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./app/index.html"
})
]
};
you do not need a '/'
output: {
path: path.join(__dirname, "dist"),
filename: "index_bundle.js"
},

webpack bundle.js not found - 404 error

I'm trying to learn Webpack configuration, and I keep getting errors in my console. It seems like my webpack app.bundle.js is not been found.
The page loads and the content of my html file displays, but not in the app.bundle.js or the html file in have in my dist directory, not untill i run mpm build.
below is the code for the webpack configuration and the error
// import node.js native path module
const path = require('path');
let webpack = require('webpack');
//require HtmlWebPackPlugin
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const port = process.env.PORT || 3000;
//define constant for paths
const paths ={
DIST: path.resolve(__dirname, 'dist'),
SRC: path.resolve(__dirname, 'src'),
JS: path.resolve(__dirname, 'src/js')
};
console.log(paths.DIST);
//webpack configuration
module.exports ={
entry: path.join(paths.JS, 'index.js'),
output: {
path: paths.DIST,
filename: 'app.bundle.js'
},
//set starting point for server
devServer: {
contentBase: paths.SRC,
host:'localhost',
port: port,
historyApiFallback: true,
open: true,
hot:true
},
//set webpack to use plugins
plugins: [
new HtmlWebpackPlugin({
template: path.join(paths.SRC, 'index.html'),
}),
new ExtractTextPlugin('style.bundle.css'),
new webpack.HotModuleReplacementPlugin()
],
//configure loaders
module: {
rules: [
//setup babel loader
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
'babel-loader',
],
},
//setup css loader
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
use: 'css-loader',
}),
},
{
test: /\.(png|jpg|gif)$/,
use: [
'file-loader',
],
},
],
},
//enable JS files without adding their extensions
resolve: {
extensions: ['.js', '.jsx'],
},
};
Here is the error on the browser console
Loading failed for the <script> with source “http://localhost:3000/js/app.bundle.js”
Source map error: request failed with status 404 Resource URL: http://localhost:3000/app.bundle.js Source Map URL: sockjs.js.map
The post is old but hopefully this helps some future person since I just solved a similar issue, here goes:
Ensure that the server root path and the output path makes sense for the files generating the 404 error.
Specifically, the server root path, set by "contentBase: paths.SRC" points to the SRC folder but the JS files are output to paths.DIST. When a browser attempts to access these files the URL it uses points to the wrong location. Fix by either changing content base to DIST, or adding publicPath: paths.DIST, which will override contentbase.
Link to references for contentBase, and publicPath.
The same error happened to me because i didn't run Webpack.
npx webpack
Run it on the same directory as Webpack configuration script.

Run Mocha specs from React app in a browser using Webpack and mocha-loader

I have a react App for which I'd like to run its mocha specs (unit-tests) in a browser. I found this SO post and tried to apply same idea to my project. I came up with the following webpack config file:
webpack.config.test.js
const nodeExternals = require('webpack-node-externals');
const path = require('path');
const host = 'localhost';
const port = '8084';
module.exports = {
target: 'web',
externals: [nodeExternals()],
entry: './specs/index.js',
output: {
filename: 'debug.bundle.js',
path: path.join(__dirname, 'tests'),
publicPath: `http://${host}:${port}/tests`,
},
devServer: {
host,
port,
},
module: {
rules: [
{
test: /\.js$/,
loaders: ['react-hot-loader', 'babel-loader'],
enforce: 'pre',
},
{
test: /.+Spec\.js$/,
loaders: ['mocha-loader'],
},
{
test: /(\.css|\.scss)$/,
loader: 'null-loader',
exclude: [
/build/,
],
},
{
test: /(\.jpg|\.jpeg|\.png|\.gif)$/,
loader: 'null-loader',
},
],
},
};
And, after starting the server with:
webpack-dev-server --config webpack.config.test.js
I get the following error in console:
I've read that the problem might be with webpack-node-externals but not really sure what's happening. Any ideas?
I think you will want to use webpack-node-externals only when you bundle files for backend (as described in plugin README). When you use it you forbid it to build all modules from node_modules folder.

How to chunk the bundle.js file?

I have created a project using react and flux architecture. Need to chunk the bundle.js file because by combining all the files it is creating a huge js file of 4mb which is causing problem in downloading on slow network so how to chunk the js file so that only the required libraries are included when a page opens
I am using webpack 1.x
my directory structure is
webpack.config.js file
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'cheap-module-source-map',
entry: [
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: ''
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({
// names: ["app", "subPageA"]
// (choose the chunks, or omit for all chunks)
children: true,
// (use all children of the chunk)
async: true,
// (create an async commons chunk)
// minChunks: 3,
// (3 children must share the module before it's separated)
})
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
}, {
test: /\.css$/,
exclude: /\.useable\.css$/,
loader: "style-loader!css-loader"
}, {
test: /\.useable\.css$/,
loader: "style-loader/useable!css-loader"
}, {
test: /\.png$/,
loaders: ["url-loader?mimetype=image/png"]
}, {
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
}]
}
};
server.js file
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true
}).listen(3000, 'localhost', function(err, result) {
if (err) {
return console.log(err);
}
console.log('Listening at http://localhost:3000/');
});
index.html file
<html>
<head>
<title>Project</title>
</head>
<body>
<div id="app" />
<script src="bundle.js" type="text/javascript"></script>
</body>
</html>
When you need a particular module, that is not required on the initial load you can use
require.ensure(["module-a", "module-b"], function() {
var a = require("module-a");
// ...
});
That way it only gets loaded when you need it, thus decreasing your bundle size.
If you use routes and react-router you can use per route code splitting as described in this article
http://moduscreate.com/code-splitting-for-react-router-with-es6-imports/
Im my experience, typically with webpack-optimize-chunk-plugin, you split your projects code into a vendor.js and a bundle.js. like this:
module.exports = {
entry:{
vendor: ["react", "react-dom"], // list all vender libraries here
app: ['./path/to/entry.js']
},
output: {
path: path.join(__dirname, './public'),
filename:'bundle.js'
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js")
]
}
So this would output a bundle.js and a vendor.js. I haven't seen webpack-optimize-chunk-plugin used in the way you described. (it would be very cool if possible).
Also I would check out all the other webpack optimization plugins to also help with the over all file size. (i.e. DedupePlugin, UglifyJsPlugin, OccurenceOrderPlugin...). More info here. Also here is an example of multi entry point that you may find helpful. Best of luck.

Categories