I have a Flask app that is serving a template index.html, which in turn access a javascript file generated by webpack. The issue is that I am generating a hash for the webpack generated file, to prevent the browser from caching, and I cannot figure out how to access the webpack generated file, as the hash name can change. For example, if the webpack generates a file called bundle-cdcf74127a4e321fbcf0.js, I would not know the hash function cdcf74127a4e321fbcf0 ahead of time, and so I could not access it in index.html.
Here is my webpack config file:
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: "./js/main.js",
output: {
filename: "static/bundle-[hash].js",
},
resolveLoader: {
moduleExtensions: ['-loader']
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-0']
}
},
{
test: /\.css$/,
loader: 'style-loader',
},
{
test: /\.css$/,
loader: 'css-loader',
query: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
]
},
plugins: [new CleanWebpackPlugin(['static/bundle*.js'])]
};
The code used to call the webpack generated file in index.html is below (this code does not work, as it appears that asterisk search does not work in the file name here):
<body>
<div id="app"></div>
<script src="bundle*.js"></script>
</body>
The flask app code goes like:
app = Flask(__name__, static_url_path='')
#app.route('/')
def default():
return render_template('index.html')
How would I fix this code so that it serves the webpack generated file?
You need to use the webpack plugin htmlWebpackPlugin, refer to https://github.com/jantimon/html-webpack-plugin#configuration.
You can provide a html template for this plugin to inject the js files generated by webpack, pay close attention to these configuration options: template , inject, chunks, 'hash'.
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
template: './index.html'
favicon: './favicon.ico',
filename: './dist/index.html'
inject: 'body',
chunks: ['vendor', 'app'],
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true
}
})
Related
When I run webpack server, Below config by default opens index.html available in public folder.
so, Instead of index.html, I want to create another.html or may be like a folder inside which an html eg. public/someFolder/another.html and want to open it, when webpack server is run.
how to run a different html file instead of index.html when webpack server runs?
webpack.config.js
const path = require("path");
module.exports = {
entry: "./myFile.js",
output: {
path: path.join(__dirname, "public"),
filename: "bundle.js",
},
module: {
rules: [
{
loader: "babel-loader",
test: /\.js$/,
exclude: /node_modules/,
},
{
test: /\.s?css$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
],
},
devtool: "cheap-module-eval-source-map",
devServer: {
contentBase: path.join(__dirname, "public"),
historyApiFallback: true,
},
};
Have a look at HtmlWebpackPlugin
You can specify a custom path and a custom .html file.
output: {
filename: './dist/subdirectory/myindex.html'
},
plugins: [new HtmlWebpackPlugin()]
The default is of course index.html
Im stuck and can't get to work my webpack configuration for loading images with src attribute from HTML. I cloned a repo with full setup of webpack, but I know there is a way to simply customize and load images directly from HTML.
Webpack.config.js 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"
}),
Before this project I was able to make that images would simply load from HTML but now ironicly im stuck and can't get this working.
Any help will be very appriciated.
When loading a image directly form HTML, I get the following error:
Error: Child compilation failed:
Module not found: Error: Can't resolve '
./src/assets/images/portret.jpg' in '/home/viktoras/www/sites/painter-new/src':
You can do this:
<img src="<%=require('./src/assets/logo.png')%>">
Plugin Conf
$new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html'
}),
I am writing an electron app using react as for the UI and webpack for bundling. Webpack is configured right now for the react part of the application as follows:
const path = require('path');
const HtmlWebPackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
mode: 'development',
entry: './src/index.tsx',
target:'node',
output: {
filename: '[name].bundle.js',
path: path.join(__dirname, 'build')
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: {
loader: 'ts-loader'
}
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader'
}
]
},
{
test: /\.css$/,
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
test: /\.scss$/,
use: [{
loader: "css-loader", options: {
sourceMap: true
}
}, {
loader: "sass-loader", options: {
sourceMap: true
}
}]
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
plugins: [
new HtmlWebPackPlugin({
template: "./index.html",
filename: "./index.html"
}),
new CopyWebpackPlugin([{ from: 'public',ignore: ['*.html'] }])
],
devtool: 'eval-source-map'
}
In my index.html I need to use the following script tag for electron's rendering process :
<script>
require('build/bundle.js')
</script>
When I run webpack-dev-server everything compiles without error, but when I open chrome dev tools I see this error :
Uncaught ReferenceError: require is not defined
at (index):12
I had to target node in my webpack.config to make electron work so I assume the require function works in browser as well since if I were to create an electron app in a pure node.js environment(without webpack and react) it works without any additional configuration. So I guess there is an issue with my webpack configuration, but I can't find any useful resource online unfortunately. Can anyone help me out? Thanks in advance!
Electron is basically a chromium browser connected to a node process through « IPC ».
This means you don’t have require available in the browser.
You need to import your script like this:
<script src="/build/bundle.js"></script>
And also you need to change the target from node to electron-renderer for the browser code.
If you also need to build code for the node side you need to add the electron-main target.
See https://webpack.js.org/configuration/
I am using the package electron-notifications and it relies on a .html and .css file in its assets folder. This assets folder is not included in webpack (1.14.0) though.
I know I should not add a module as an entry point. I have come across a concept called code splitting, but I'm not clear on how that works and if that is what I need to be looking into further. Any advice you can give would be greatly appreciated.
webpack.config.production.js
import path from 'path';
import webpack from 'webpack';
import validate from 'webpack-validator';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import merge from 'webpack-merge';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import BabiliPlugin from 'babili-webpack-plugin';
import baseConfig from './webpack.config.base';
export default validate(merge(baseConfig, {
devtool: 'inline-source-map',
entry: [
'babel-polyfill',
'./app/index'
],
output: {
path: path.join(__dirname, 'app/dist'),
publicPath: '../dist/'
},
module: {
loaders: [
// Extract all .global.css to style.css as is
{
test: /\.global\.css$/,
// loaders: [
loader: ExtractTextPlugin.extract(
'style-loader',
'css-loader?sourceMap'
)
// ]
},
// Pipe other styles through css modules and append to style.css
{
test: /^((?!\.global).)*\.css$/,
// loaders: [
loader: ExtractTextPlugin.extract(
'style-loader',
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
)
},
// Fonts
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff' },
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff' },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml' },
// Images
{
test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
loader: 'url-loader'
}
]
},
plugins: [
// https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin
// https://github.com/webpack/webpack/issues/864
new webpack.optimize.OccurrenceOrderPlugin(),
// NODE_ENV should be production so that modules do not perform certain development checks
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new BabiliPlugin(),
new ExtractTextPlugin('style.css', { allChunks: true }),
new HtmlWebpackPlugin({
filename: '../app.html',
template: 'app/app.html',
inject: false
})
],
// https://github.com/chentsulin/webpack-target-electron-renderer#how-this-module-works
target: 'electron-renderer'
}));
If you want that packages' CSS to be recognised by the webpack, you just add it to the style's(CSS's) loader block, as an include attribute along with "test" and "loader". In the include attribute point it to the node_modules/electron_notification path.
HTML of that package need not be included, since your Single Page Application, has it's own HTML, if needed try to replicate the class names there. But I doubt if you need to do that.
I have been breaking my head with webpack and angular. This might have a simple answer but I cant figure it out. I have read almost every answer here in stack overflow on this topic to no avail.
I have an html page like this (also other template that have images):
<body>
<img ng-src="../images/angular-webpack.png">
<md-button class="md-primary md-raised">
Button
</md-button>
</body>
I also have a webpack config:
var webpack = require('webpack');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var path = require('path');
module.exports = {
context: path.resolve(__dirname + '/src'),
entry: ['./js/core/app.module.js'],
output: {
path: './release',
publicPath:'/',
filename: 'app.js'
},
module: {
loaders: [
{
test: /\.html/,
exclude: 'node_modules',
loader: 'raw-loader'
},
{
test: /\.css/,
exclude: 'node_modules',
loader: 'style-loader!css-loader'
},
{
test: /\.(jpe?g|png)$/i,
exclude: 'node_modules',
loader: 'url-loader?limit=8192!img'
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new CopyWebpackPlugin([
{from: './index.html', to: './index.html'}
], {
ignore: [
'*.txt',
{glob: '**/*', dot: true}
]
})
],
devServer: {
contentBase: './release'
},
watch: true
};
...but i do not see my images loading. I have tried url-loader, file-loader with publicPath and without it. I am confused, I do not know how to format the webpack config or the html image tag for it to work.
Anyone has any experience on getting images to work with webpack? Also I do not want to include my images in the controllers or any other js file. I want the images to be declared in the html page.
The raw-loader is supposed to turn a text file into a CommonJS module that exports the file contents as a string – nothing more.
If you want webpack to recognize the file as HTML and all its references in it, you need the html-loader. The html-loader parses the given file with an HTML parser and picks up references to other files within attributes. By default, that is only <img src="...">. In your case, you need to tell the html-loader to also look for ng-src attributes, like this:
// webpack.config.js
...
loaders: [{
test: /\.html$/,
loaders: [
"html?" + JSON.stringify({
attrs: ["img:src", "img:ng-src"]
})
]}
]