Skip to content

Commit

Permalink
client,webserver: webpack build ID used as browser cache ID.
Browse files Browse the repository at this point in the history
	- Emit a webpack build ID when building site and store in webpack-build-id.txt

	- Embed the webpack build ID into bodybuilder as a url query string:-
	  webpackBuildIdQuery fetches latest webpack build from the webpack-build-id.txt
	  file in app site directory and makes it available to append to the main css
	  link and to the main script link in bodybuilder; this should cause no reload
	  of the main css/js files if they are already cached by the browser.
	  If webpackBuildIdFile is not found return a fallback query that will make the
	  browser reload css/js.

	- Some eslint in webpack dir.
  • Loading branch information
dev-warrior777 committed Dec 5, 2024
1 parent cf944a5 commit 29fbf7c
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ dex/testing/loadbot/loadbot
bin/
bin-v*/
client/webserver/site/template-builder/template-builder
client/webserver/site/webpack-build-id.txt
dex/testing/btc/harnesschain.tar.gz
client/asset/btc/electrum/example/server/server
client/asset/btc/electrum/example/wallet/wallet
Expand Down
4 changes: 2 additions & 2 deletions client/webserver/site/src/html/bodybuilder.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<link rel="icon" href="/img/favicon.png?v=AZ4AZX">
<meta name="description" content="Bison Wallet">
<title>{{.Title}}</title>
<link href="/css/style.css" rel="stylesheet">
<link href="/css/style.css{{webpackBuildIdQuery}}" rel="stylesheet">
</head>
<body {{if .UseDEXBranding}}class="dex-branding"{{end}}>
<div class="popup-notes d-hide" id="popupNotes">
Expand Down Expand Up @@ -257,7 +257,7 @@
</div>
</div>

<script src="/js/entry.js"></script>
<script src="/js/entry.js{{webpackBuildIdQuery}}"></script>
</body>
</html>
{{end}}
6 changes: 4 additions & 2 deletions client/webserver/site/src/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export default class Application {
authed: boolean
user: User
seedGenTime: number
webpackBuildID: string
showPopups: boolean
loggers: Record<string, boolean>
recorders: Record<string, LogMessage[]>
Expand All @@ -184,13 +185,14 @@ export default class Application {
this.notes = []
this.pokes = []
this.seedGenTime = 0
this.webpackBuildID = process.env.WEBPACK_BUILD_ID || ''
this.noteReceivers = []
this.fiatRatesMap = {}
this.showPopups = State.fetchLocal(State.popupsLK) === '1'
this.txHistoryMap = {}
this.requiredActions = {}

console.log('Bison Wallet')
console.log('Bison Wallet', 'Webpack Build Id:', this.webpackBuildID)

// Set Bootstrap dark theme attribute if dark mode is enabled.
if (State.isDark()) {
Expand Down Expand Up @@ -259,7 +261,7 @@ export default class Application {
// Don't fetch the user until we know what page we're on.
await this.fetchUser()
const ignoreCachedLocale = process.env.NODE_ENV === 'development'
await intl.loadLocale(this.lang, ignoreCachedLocale)
await intl.loadLocale(this.lang, this.webpackBuildID, ignoreCachedLocale)
// The application is free to respond with a page that differs from the
// one requested in the omnibox, e.g. routing though a login page. Set the
// current URL state based on the actual page.
Expand Down
6 changes: 3 additions & 3 deletions client/webserver/site/src/js/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,16 +222,16 @@ export const ID_DELETE_BOT = 'DELETE_BOT'

let locale: Locale

export async function loadLocale (lang: string, skipCache: boolean) {
export async function loadLocale (lang: string, buildID: string, skipCache: boolean) {
if (!skipCache) {
const specs = State.fetchLocal(State.localeSpecsKey)
if (specs && specs.lang === lang) {
if (specs && specs.lang === lang && specs.webpackBuildID === buildID) { // not stale
locale = State.fetchLocal(State.localeKey)
return
}
}
locale = await postJSON('/api/locale', lang)
State.storeLocal(State.localeSpecsKey, { lang })
State.storeLocal(State.localeSpecsKey, { lang, buildID })
State.storeLocal(State.localeKey, locale)
}

Expand Down
1 change: 1 addition & 0 deletions client/webserver/site/src/js/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,7 @@ export interface Application {
exchanges: Record<string, Exchange>
fiatRatesMap: Record<number, number>
showPopups: boolean
webpackBuildID: string
authed: boolean
start (): Promise<void>
reconnected (): void
Expand Down
2 changes: 1 addition & 1 deletion client/webserver/site/webpack/analyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = merge(common, {
rules: [{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
exclude: /node_modules/
}]
},
optimization: {
Expand Down
27 changes: 22 additions & 5 deletions client/webserver/site/webpack/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,24 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const StyleLintPlugin = require('stylelint-webpack-plugin')
const ESLintPlugin = require('eslint-webpack-plugin')

const child_process = require('child_process')
const fs = require('node:fs')
const buildIdFilename = 'webpack-build-id.txt'

function randBuildId () {
const buildID = JSON.stringify(Math.floor(Math.random() * 1000000000)).trim()
console.log('WEBPACK_BUILD_ID:', buildID)
fs.writeFile(buildIdFilename, buildID, err => {
if (err) {
console.error(err)
} else {
console.log(' ', buildID, ' written to ', buildIdFilename)
}
})
return buildID
}

module.exports = {
target: "web",
target: 'web',
module: {
rules: [
{
Expand All @@ -26,7 +40,7 @@ module.exports = {
{
loader: 'sass-loader',
options: {
implementation: require("sass"), // dart-sass
implementation: require('sass'), // dart-sass
sourceMap: true
}
}
Expand All @@ -35,12 +49,15 @@ module.exports = {
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.WEBPACK_BUILD_ID': randBuildId()
}),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: '../dist/style.css'
}),
new StyleLintPlugin({
threads: true,
threads: true
}),
new ESLintPlugin({
extensions: ['ts'],
Expand All @@ -53,7 +70,7 @@ module.exports = {
publicPath: '/dist/'
},
resolve: {
extensions: ['.ts', ".js"],
extensions: ['.ts', '.js']
},
// Fixes weird issue with watch script. See
// https://github.com/webpack/webpack/issues/2297#issuecomment-289291324
Expand Down
2 changes: 1 addition & 1 deletion client/webserver/site/webpack/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = merge(common, {
rules: [{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
exclude: /node_modules/
}]
},
devtool: 'inline-source-map'
Expand Down
2 changes: 1 addition & 1 deletion client/webserver/site/webpack/prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = merge(common, {
usedExports: true,
minimize: true,
minimizer: [
`...`, // extend webpack 5's TerserPlugin
'...', // extend webpack 5's TerserPlugin
new CssMinimizerPlugin({})
]
},
Expand Down
37 changes: 37 additions & 0 deletions client/webserver/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"html/template"
"io/fs"
"os"
"path/filepath"
"strings"

"decred.org/dcrdex/client/intl"
Expand All @@ -17,6 +18,8 @@ import (
"golang.org/x/text/language"
)

const webpackBuildIdFile = "webpack-build-id.txt"

// pageTemplate holds the information necessary to process a template. Also
// holds information necessary to reload the templates for development.
type pageTemplate struct {
Expand Down Expand Up @@ -184,6 +187,37 @@ func (t *templates) exec(name string, data any) (string, error) {
return page.String(), err
}

// webpackBuildIdQuery fetches latest webpack build from the webpack-build-id.txt
// file in app site directory and makes it available to append to the main css
// link and to the main script link in bodybuilder; this should cause no reload
// of the main css/js files if they are already cached by the browser.
// If webpackBuildIdFile is not found return a fallback query that will make the
// browser reload css/js.
var webpackBuildIdQuery = func() string {
var fallbackQueryStr = "?v=1"
d, _ := os.Getwd()
cwd := filepath.Base(d)
if cwd != "bisonw" {
return fallbackQueryStr
}
d = filepath.Dir(d)
cmd := filepath.Base(d)
if cmd != "cmd" {
return fallbackQueryStr
}
d = filepath.Dir(d)
client := filepath.Base(d)
if client != "client" {
return fallbackQueryStr
}
f := filepath.Join(d, "/webserver/site", webpackBuildIdFile)
wpB, err := os.ReadFile(f)
if err != nil {
return fallbackQueryStr
}
return "?v=" + string(wpB)
}()

// templateFuncs are able to be called during template execution.
var templateFuncs = template.FuncMap{
"toUpper": strings.ToUpper,
Expand Down Expand Up @@ -212,4 +246,7 @@ var templateFuncs = template.FuncMap{
}
return parts[0]
},
"webpackBuildIdQuery": func() string {
return webpackBuildIdQuery
},
}

0 comments on commit 29fbf7c

Please sign in to comment.