how can i get the lang html attribute in webpack configuration - javascript

const lang = "the lang html attribute value";
var languages = {
"fr": require("./languages/fr.json"),
"en": require("./languages/en.json")
};
var configuration = Object.keys(languages).map(function(language) {
const loadedLang = (lang.indexOf("fr") > -1) ? "fr" : "en";
return {
name: loadedLang,
entry: './assets/js/main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'assets/js/dist')
},
plugins: [
new I18nPlugin(
languages[loadedLang]
)
]
}
});
So I am trying to get the <html lang="en-US"> lang attribute and I know that I have no access to the DOM from the webpack config file.
My question is:
Does someone have an idea about how to do this or how to have access to the local storage from webpack?
PS:
I tried a node-localstorage package but it doesn't do the job I want

An answer to your question would be to load the file with the fs api and then use an regex to extract your language:
const fs = require('fs');
const content = fs.readFileSync('PATH_TO_INDEX.HTML', options: { encoding: 'utf8' });
const lang = content.match(/<html lang="(.*)"/)[1];
But I would recommend to do it the "webpack" way:
Create a separate folder for every language, that contains the index.html and the js file specific to each language language.
For this, add the following:
output: {
path: path.resolve(__dirname, `assets/js/dist/${language}/`)
},
plugins: [
new HtmlWebpackPlugin({
template: 'PATH_TO_YOUR_TEMPLATE',
lang: language,
title: 'your page title',
})
]
Please don't forget to install the html-webpack-plugin and require it at the top of your config.
And create a new file index.html with the following content:
<!DOCTYPE html>
<html lang="<%= htmlWebpackPlugin.options.lang %>">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>
So now for every language a separate index.html with the right language and the right js file for that language is created in every language folder.
So not the html file dictates the language set, but the webpack config.

Related

"Uncaught ReferenceError: printMe is not defined" at onload method in HTML

I'm currently trying to get started using webpack and ran into "Uncaught ReferenceError: printMe is not defined" error when trying to call my "init" method from HTML using the onload tag despite exporting the methods. My files are as follows:
print.js (located in /resources/static):
export function printMe() {
console.log("Hi");
}
index.js (located in /resources/static):
import {printMe} from "./print";
export function component() {
const element = document.createElement('div');
const btn = document.createElement('button');
btn.innerHTML = 'Click me and check the console!';
btn.onclick = printMe;
element.appendChild(btn);
return element;
}
export function init() {
console.log("init ran");
}
document.body.appendChild(component());
webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './resources/static/index.js',
},
devtool: 'inline-source-map',
plugins: [
new HtmlWebpackPlugin({
title: 'Output Management',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean:true,
},
};
index.html (located in /dist):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Output Management</title>
<meta name="viewport" content="width=device-width, initial-scale=1"><script defer src="index.bundle.js"></script></head>
<body onload="init()">
</body>
</html>
index.bundle.js (located in /dist) I'm not going to include this file as I don't believe it to be necessary to the solution, although is important to note that it is actually there. Any help is appreciated
Even though you say export, I think that webpack isn't including it in your bundle since you never use the function in the JavaScript code. You'll either need a plugin to monitor your HTML, or use addEventListener on the body to add an "onLoad" event handler.
The simplest way to do this is with the event listener (don't include parentheses after init; see Why is the method executed immediately when I use setTimeout?):
document.body.addEventListener('load', init);

Webpack serve does not include exports on var

I'm working on a project using webpack, I'm trying to use the webpack-dev-serve package to preview my changes. However when I start the server and load the page the object created by webpack does not have the functions on it Uncaught TypeError: test.a is not a function, when I console log the object webpack creates I can see its an empty object Object { }. Using the exact same webpack config to build the package and including it on my page works fine.
Here is my webpack.config:
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: "./src/index.js",
target: "web",
output: {
filename: "test.js",
library: {
name: "test",
type: "var"
}
},
module: {
rules: [{
exclude: /node_modules/
}]
},
resolve: {
symlinks: false
},
plugins: [
new HtmlWebpackPlugin({
title: "Development",
template: "./src/index.html",
scriptLoading: "blocking",
inject: "head"
})
]
};
My index.js is very simple:
export function a(){
console.log("A has been called");
}
My index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<script>
console.log(test);
test.a();
</script>
</body>
</html>
I found a fix from the problem here:
WebPack output.library.type var is undefined
After adding injectClient: false to devServer, and removing scriptloading and inject from the HtmlWebpackPlugin config, webpack serve now works as expects.

Webpack to only inject variables into HTML

I am using a basic example of the HtmlWebpackPlugin to inject variables into my HTML page. I do not have an index.js and do not want the bundle.js. How can I exclude the dist bundle.js and only output the updated HTML?
webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
title: 'HTML Webpack Plugin',
bar: 'bar'
})
]
};
index.html (the template):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= JSON.stringify(htmlWebpackPlugin.options.title) %></title>
<script><script src="<%=htmlWebpackPlugin.options.favWord%>/socket.io.js"></script></script>
</head>
<body>
<h1>Hello, Webpack!</h1>
<p> My favorite word is <%= JSON.stringify(htmlWebpackPlugin.options.bar) %> </p>
</body>
</html>
The HTML page is generated perfectly, just I do not want the bundle.js generated.
Old question, but for anyone else with the same issue, you can set the inject option to false.
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
title: 'HTML Webpack Plugin',
bar: 'bar',
inject: false,
}),
];

Inline css from cdn by vue-style-loader

I want to pass my css class style into html tag in .vue file.
my vue loader setting in webpack.config.js:
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: ExtractTextPlugin.extract({
use: 'css-loader',
fallback: 'vue-style-loader'
})
}
}
},
however, I dont know how to configure the plugin:
plugins: [
new ExtractTextPlugin("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css")
]
and I even don't know if vue-style-loader could do this for me. Could anybody tell me how to embed my styles (cdn or single css file) into html tag , thanks.
I finally find a solution: I did not use webpack to compile the template. I try to pass the html content to server side (node.js , not necessary, you could do it in client side), and use inline-css to embed the style into related tags. Maybe it's not the best solution, but it does resolve my problem. If anyone gets better anwser , please don't hesitate to tell me.
exports.convertHtmlToDocx = function(req,res){
const HtmlDocx = require('html-docx-js');
const fs = require("fs");
const body = req.body;
let html = req.body.html;
html = `<!DOCTYPE html>
<html>
<head>
<style>
p{color:red;}
</style>
<link rel="stylesheet" href="localhost:3000/stylesheets/bootstrap-3.3.7/dist/css/bootstrap.css"></link>
</head>
<body>${html}</body>
</html>`;
const options = {
url: 'localhost:3000'
}
const inlineCss = require('inline-css');
inlineCss(html, options)
.then(function(html) {
console.log(html)
});
}
client side:
const apiUrl = '';
import axios from 'axios'
api.exportDocx = function(param, callback){
//param: { html: '<div><p>xxxxx</p></div>'} ....
axios.post(`${apiUrl}/convertHtmlToDocx`,param).then(result => {
callback(result)
});
}

Webpack - Cache busting using auto-versioning with hash values

I've been trying for weeks to get cache busting to work with Webpack, pouring through posts, documentation, and the documentation of each added plugin, but I can't figure out how to get it right. I want to cache-bust using hashes, and not using query parameters. This is my current configuration -- everything commented w/ * means that it was included purely for the sake of cache-busting:
var path = require('path');
var webpack = require('webpack');
var AssetsPlugin = require('assets-webpack-plugin'); // *
var HtmlWebpackPlugin = require('html-webpack-plugin'); // *
var WebpackMd5Hash = require('webpack-md5-hash'); // *
var basePlugins = [
new webpack.DefinePlugin({
__PRODUCTION__: true,
'process.env.NODE_ENV': JSON.stringify('production'),
}),
];
var usedPlugins = [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false,
},
}),
new webpack.optimize.CommonsChunkPlugin({ // *
names: "manifest" // *
}), // *
new AssetsPlugin(), // *
new HtmlWebpackPlugin(), // *
new WebpackMd5Hash(), // *
];
/* Config */
module.exports = {
entry: {
main: [path.join(__dirname, '/lib/main')],
},
eslint: {
configFile: 'lib/.eslintrc',
},
resolve: {
root: path.resolve(__dirname, 'lib'),
alias: {
... // a bunch of aliases
},
},
output: {
path: path.join(__dirname, '/pub/'),
filename: '[name].[chunkhash].js', // *
chunkFilename: '[name].[chunkhash].js', // *
sourceMapFilename: '[name].js.map',
publicPath: '/pub/',
},
plugins: usedPlugins,
module: {
preLoaders: [
... // some preloaders
],
loaders: [
... // some loaders
],
},
};
When I build this in production, under prodBuild/pub folder, I get 3 files:
main.[someHashHereButWithoutTheBrackets].js
manifest.[someOtherHashHereAndAlsoWithoutTheBrackets].js
index.html
The index.html under pub is generated even though there's an index.html under prodBuild, which is the html page that is served to the client.
So the file structure looks something like this:
/prodBuild
/pub
main.[someHashHereButWithoutTheBrackets].js
manifest.[someOtherHashHereAndAlsoWithoutTheBrackets].js
index.html // call this indexB
/anotherFolder1
...
/anotherFolderK
index.html // call this indexA
Again, without any of this attempt at cache-busting, indexA is what is served to the client. In it there a number of script tags such as:
<script src="pub/main.js></script> // in indexA
However, in indexB, not only are there other missing html tags, but I only get two script tags:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Broken Webpack App</title>
</head>
<body>
<script type="text/javascript" src="/pub/manifest.[someOtherHashHereAndAlsoWithoutTheBrackets].js"></script><script type="text/javascript" src="/pub/main.[someHashHereButWithoutTheBrackets].js"></script></body>
</html>
So while it appears the hashing is working (and that is what I want), there are still several issues:
The hashing does not appear in the correct index.html file, i.e. it shows up in indexB, not indexA.
indexB contains only two of the scripts that are in indexA.
In indexB, there are many html tags that are missing, but are present in indexA.
To recap, what I need is cache-busting, using the type of hashing I have described above. I am not at all versed in webpack, but what I would presume to be the end result is indexA to be exactly the same, except with hashes on the file name.
What needs to be done to get cache-busting properly working?
UPDATE:
I do not mean a hashtag as Thomas has referenced. I mean a hash value, as I've described in my post.

Categories