open-code-review/pages/webpack.config.js
hezheng.lsw 022ed75682
feat(pages): add Docs page with search, markdown rendering, and i18n support (#273)
* feat(pages): add Docs page with search, markdown rendering, and i18n support

- Add DocsPage with full-text search modal (⌘K trigger)
- Add MarkdownRenderer with DOMPurify sanitization
- Add bilingual docs content (en/zh) for all sections
- Add shared headingId utility for consistent TOC anchors
- Add search keyboard hints with i18n support
- Update Navbar with Docs navigation link
- Add icon-search.svg asset
- Configure webpack for markdown imports

* fix(pages): address PR #273 code review feedback

- Replace marked.setOptions() with new Marked instance (no global mutation)
- Escape heading ID attribute value to prevent XSS
- Use crypto.randomUUID() for mermaid diagram IDs (no collisions)
- Add cancellation flag for async mermaid renders on unmount
- Move inline <pre> styles to CSS class (only dynamic align-items inline)
- Move @types/dompurify to devDependencies
- Remove @ts-nocheck from docs/index.ts
- Extract getRawContent helper to reduce duplication
- Fix searchDocs fallback consistency (add enDocs fallback)
- Fix heading ID mismatch by stripping markdown links before ID generation
- Separate sidebar chevron (expand) from label (navigate)
- Guard ⌘K shortcut against input/textarea focus interception
2026-07-03 11:45:33 +08:00

65 lines
1.5 KiB
JavaScript

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: process.env.NODE_ENV === 'production' ? '/open-code-review/' : '/'
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-react', { development: process.env.NODE_ENV !== 'production' }],
'@babel/preset-env',
'@babel/preset-typescript'
]
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
},
{
test: /\.svg$/,
type: 'asset/resource'
},
{
test: /\.(png|jpg|jpeg|gif)$/,
type: 'asset/resource'
},
{
test: /\.md$/,
type: 'asset/source'
}
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
devServer: {
port: 3030,
host: '0.0.0.0',
allowedHosts: 'all',
static: { directory: __dirname },
historyApiFallback: {
index: '/index.html',
rewrites: [{ from: /^\/\_p\/\d+\//, to: '/index.html' }]
}
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
inject: 'body'
})
]
};