Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve webpack configs #37

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions .github/workflows/bundle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,8 @@ jobs:
- name: Lint project
run: npm run lint-project

- name: Build bundle
run: npx webpack

- name: Generate example
run: |
npx antora antora-playbook-ru.yml
npx antora antora-playbook-en.yml
- name: Build bundle and generate docs
run: npm run build

- name: Upload bundle
if: inputs.upload
Expand Down
4 changes: 2 additions & 2 deletions antora-playbook-en.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
site:
title: Taymyr Antora UI
url: /
url: /en
start_page: ROOT::index.adoc
content:
sources:
Expand All @@ -15,7 +15,7 @@ ui:

output:
clean: false
dir: build/site
dir: build/site/en

antora:
extensions:
Expand Down
7 changes: 7 additions & 0 deletions config/constants/Env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const mode = process.env.NODE_ENV

export const Env = {
isDev: mode === 'development',
isProd: mode === 'production',
cwd: process.cwd(),
}
33 changes: 33 additions & 0 deletions config/helpers/htmlPlugin/createHtmlPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import HtmlWebpackPlugin from 'html-webpack-plugin'
import get from 'lodash/get'

interface IHtmlPluginCreatingOptions {
fileName: string
filterKey: string
filterValue: string
filterByTagNode?: (tagNode: Record<string, unknown>) => boolean
}

export const createHtmlPlugin = (config: IHtmlPluginCreatingOptions) => {
const { fileName, filterKey, filterValue, filterByTagNode = () => true } = config

const getTemplateContent: HtmlWebpackPlugin.Options['templateContent'] = htmlWebpackPlugin => {
return (
htmlWebpackPlugin.tags.headTags
.filter(
(tagNode: Record<string, unknown>) =>
get(tagNode, filterKey) === filterValue && filterByTagNode(tagNode),
)
.join('')
// It must be Handlebars template with root path as variable
.replaceAll('uiRootPath', '{{{uiRootPath}}}')
)
}

return new HtmlWebpackPlugin({
publicPath: 'uiRootPath',
templateContent: ({ htmlWebpackPlugin }) => `${getTemplateContent(htmlWebpackPlugin)}`,
filename: fileName,
inject: false,
})
}
1 change: 1 addition & 0 deletions config/helpers/htmlPlugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { createHtmlPlugin } from './createHtmlPlugin'
6 changes: 6 additions & 0 deletions config/helpers/htmlPlugin/types/IHtmlPluginCreatingOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface IHtmlPluginCreatingOptions {
fileName: string
filterKey: string
filterValue: string
filterByTagNode?: (tagNode: Record<string, unknown>) => boolean
}
1 change: 1 addition & 0 deletions config/helpers/htmlPlugin/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { IHtmlPluginCreatingOptions } from './IHtmlPluginCreatingOptions'
1 change: 1 addition & 0 deletions config/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { spawnCommand } from './spawnCommand'
29 changes: 29 additions & 0 deletions config/helpers/spawnCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { spawn, SpawnOptions } from 'node:child_process'

export const spawnCommand = (commandStr: string, options?: SpawnOptions) => {
const [command, ...args] = commandStr.split(' ')

if (!command) return Promise.reject()

return new Promise((resolve, reject) => {
const spawnedProcess = spawn(command, args, {
shell: true,
stdio: 'inherit',
env: { FORCE_COLOR: 'true', ...process.env },
...options,
})

spawnedProcess.stdout?.on('data', data => {
console.log(data.toString())
})

spawnedProcess?.on('close', code => {
if (code === 1) {
//eslint-disable-next-line
reject()
}

resolve(null)
})
})
}
21 changes: 21 additions & 0 deletions config/plugins/BuildAntoraPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Compiler } from 'webpack'
import { spawnCommand } from '../helpers/spawnCommand'

export class BuildAntoraPlugin {
apply(compiler: Compiler) {
let shouldUpdateAntora = true
compiler.hooks.done.tap('Build antora', async stats => {
if (shouldUpdateAntora) {
await spawnCommand('npm run build-antora')
shouldUpdateAntora = false
setTimeout(() => {
compiler.hooks.done.callAsync(stats, () => {
return
})
}, 500)
} else {
shouldUpdateAntora = true
}
})
}
}
73 changes: 73 additions & 0 deletions config/webpack.common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// eslint-disable-next-line import/default
import CopyPlugin from 'copy-webpack-plugin'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import path from 'path'
import type { Configuration } from 'webpack'
// Compiler's webpack annotations are incompatible in types package:(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import ZipPlugin from 'zip-webpack-plugin'
import { Env } from './constants/Env'
import { createHtmlPlugin } from './helpers/htmlPlugin'
import { BuildAntoraPlugin } from './plugins/BuildAntoraPlugin'

const bundleName = 'ui-bundle'
const HbsPartialsPath = {
HEAD_ICONS: 'partials/head-icons.hbs',
HEAD_STYLES: 'partials/head-styles.hbs',
BODY_ASSETS: 'partials/body-assets.hbs',
}

const config: Configuration = {
entry: path.resolve(Env.cwd, './src/index.ts'),
module: {
rules: [
{
test: /\.(sc|sa|c)ss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader'],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: './css/[name].[contenthash].css',
}),
createHtmlPlugin({
fileName: HbsPartialsPath.HEAD_ICONS,
filterKey: 'meta.plugin',
filterValue: 'favicons-webpack-plugin',
}),
createHtmlPlugin({
fileName: HbsPartialsPath.HEAD_STYLES,
filterKey: 'attributes.rel',
filterValue: 'stylesheet',
}),
createHtmlPlugin({
fileName: HbsPartialsPath.BODY_ASSETS,
filterKey: 'tagName',
filterValue: 'script',
}),
new CopyPlugin({
patterns: [
{ from: 'src/layouts', to: 'layouts' },
{
from: 'src/partials',
to: 'partials',
filter: filepath =>
!Object.values(HbsPartialsPath).some(hbsPartialPath =>
filepath.endsWith(hbsPartialPath),
),
},
],
}),
new ZipPlugin({ filename: bundleName }),
new BuildAntoraPlugin(),
],
performance: {
assetFilter: (filename: string) => {
return !filename.startsWith(bundleName)
},
},
}

export default config
36 changes: 36 additions & 0 deletions config/webpack.dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import path from 'path'
import type { Configuration, WebpackOptionsNormalized } from 'webpack'
import { merge } from 'webpack-merge'
import WatchExternalFilesPlugin from 'webpack-watch-files-plugin'
import { Env } from './constants/Env'
import commonConfig from './webpack.common'

const watchedFiles = [path.resolve(Env.cwd, 'docs/**/*'), path.resolve(Env.cwd, 'src/**/*')]

const config = merge<WebpackOptionsNormalized | Configuration>(commonConfig, {
mode: 'development',
target: 'web',
output: {
filename: 'js/[name].js',
},
devServer: {
port: 4224,
static: {
directory: path.resolve(Env.cwd, 'build'),
},
open: ['/site/en'],
compress: true,
hot: true,
devMiddleware: {
writeToDisk: true,
},
},
devtool: 'source-map',
plugins: [
new WatchExternalFilesPlugin({
files: watchedFiles,
}),
],
})

export default config
22 changes: 22 additions & 0 deletions config/webpack.prod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import FaviconsPlugin from 'favicons-webpack-plugin'
import path from 'path'
import type { Configuration } from 'webpack'
import { merge } from 'webpack-merge'
import commonConfig from './webpack.common'

const config = merge<Configuration>(commonConfig, {
mode: 'production',
output: {
filename: 'js/[name].js?v=[hash]',
},
plugins: [
new FaviconsPlugin({
logo: 'logo.svg',
favicons: { appName: 'Taymyr' },
prefix: 'assets/[contenthash]/',
inject: htmlPlugin => path.basename(htmlPlugin.options.filename).endsWith('head-icons.hbs'),
}),
],
})

export default config
Loading