<base> 基于窗口对象的动态标签



我需要设置一个基于document.location的基本标记我正在使用webpack5并做出反应。

这是我的webpack配置

const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const packageDirName = process.cwd();
const paths = {
src: path.resolve(packageDirName, "src"),
dist: path.resolve(packageDirName, "../../dist"),
};
module.exports = {
entry: paths.src,
output: {
filename: "main.js",
path: paths.dist,
clean: true,
// publicPath: '/', //need to use it only on dev.
},
module: {
rules: [
{
test: /.jsx?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
rootMode: "upward",
},
},
},
{
test: /.scss$/i,
use: ["style-loader", "css-loader", "sass-loader"],
},
{test: /.(jpg|jpeg|png|woff|woff2|eot|ttf|svg)$/,loader: 'url-loader'}
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin(getEnvVars("npm_package_version", "API_BASE_URL")),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "public/index.html"),
favicon: path.resolve(__dirname, "public/favicon.ico"),
inject: true,
}),
],
devServer: {
historyApiFallback: true,
hot: true,
open: true,
// ...
},
};

在index.html上,我添加了以下代码,它调整了的基本标签(内部(

<script type="text/javascript">
const baseURL = document.location.href.includes('/me') ? `${document.location.href.split('/me')[0]}/me/` : '/';
console.log('baseURL', baseURL);
const baseDirEl = document.createElement('base');
baseDirEl.setAttribute('href', baseURL);
document.getElementsByTagName('head')[0].appendChild(baseDirEl);
</script>

webpack正在index.html<script defer src="main.js"></script>中注入此内容

main.js被提取了两次,可能是在标记之前被触发的

  1. 对于此链接:http://example.com/me
  • http://example.com/main.js-不是
  • http://example.com/me/main.js-没关系
  1. http://example.com/en/me
  • http://example.com/en/main.js-不是
  • http://example.com/en/me/main.js-没关系
  1. http://example.com/en/me/x/y/z
  • http://example.com/en/me/x/y/main.js-不是
  • http://example.com/en/me/main.js-没关系

有没有办法避免第一次获取捆绑包?直到我的脚本完成生成基本标记?或者是否有更好的方法来解决这个问题?

谢谢。

假设您有一个呈现html文件的服务器。

您可以使用webpack的publicPath属性来简化解决方案。

我的技巧是注入一个ejs变量,并在呈现HTML时更改它的值。

// webpack.config.js
const isDev = process.env.NODE_ENV === 'development';
module.exports = {
entry: paths.src,
output: {
filename: "main.js",
path: paths.dist,
clean: true,
publicPath: isDev ? '/': '/<%= lng %>me/',
// -----------------------^ this is the trick 
},
...
}

然后,当您在服务器上渲染html时,传递lng参数,如果没有语言,则该参数的值将为en/或不为任何值。

// server.js
var express = require('express');
var app = express();
// set the view engine to ejs
app.set('view engine', 'ejs'); // define ejs
// index page
app.get('/', function (req, res) {
const lng = req.lng ? `${req.lng}/` : '';
res.render('pages/index', {
lng,
});
});

最新更新