163 lines
3.5 KiB
JavaScript
163 lines
3.5 KiB
JavaScript
const path = require('path');
|
|
const fs = require('fs');
|
|
const marked = require('marked');
|
|
|
|
const CopyPlugin = require('copy-webpack-plugin');
|
|
// const CompressionPlugin = require("compression-webpack-plugin")
|
|
|
|
const renderer = new marked.Renderer()
|
|
renderer.link = (href, title, text) => {
|
|
if(href === null)
|
|
{
|
|
return text
|
|
}
|
|
let out = '<a href="' + href + '"'
|
|
if(title)
|
|
{
|
|
out += ' title="' + title + '"'
|
|
}
|
|
if(href.startsWith('http'))
|
|
{
|
|
out += ' target="_blank" rel="noreferrer noopener nofollow"'
|
|
}
|
|
out += '>' + text + '</a>'
|
|
return out
|
|
}
|
|
renderer.image = (href, title, text) => {
|
|
if (href === null) {
|
|
return text;
|
|
}
|
|
|
|
let out = '<img src="' + href + '" alt="' + text + '"';
|
|
if (title) {
|
|
out += ' title="' + title + '"';
|
|
}
|
|
else
|
|
{
|
|
out += ' title="' + text + '"';
|
|
}
|
|
out += '/>';
|
|
return out;
|
|
}
|
|
|
|
marked.setOptions({ renderer: renderer })
|
|
|
|
class BlogListingPlugin
|
|
{
|
|
static default_options = {
|
|
output_file: 'blog_list.json',
|
|
}
|
|
|
|
constructor(options = {})
|
|
{
|
|
this.options = {...BlogListingPlugin.default_options, ...options}
|
|
}
|
|
|
|
apply(compiler)
|
|
{
|
|
const plugin_name = BlogListingPlugin.name
|
|
const { webpack } = compiler
|
|
compiler.hooks.thisCompilation.tap(
|
|
plugin_name,
|
|
(compilation) => {
|
|
compilation.hooks.processAssets.tapAsync(
|
|
{
|
|
name: plugin_name,
|
|
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE
|
|
},
|
|
(compilationAssets, callback) => {
|
|
let content = []
|
|
Object.keys(compilationAssets).forEach((file_path) => {
|
|
if(file_path.startsWith('blog') && file_path.endsWith('.md'))
|
|
{
|
|
const file_name = path.basename(file_path).slice(0, -3)
|
|
const blog_info = path.basename(path.dirname(file_path)).split('_')
|
|
const blog_date = blog_info[0]
|
|
const blog_entry = blog_info.slice(1).join('_')
|
|
compilation.emitAsset(
|
|
'blog/' + blog_date + '_' + blog_entry + '/' + file_name + '.html',
|
|
new webpack.sources.RawSource(
|
|
marked(
|
|
new TextDecoder('utf-8').decode(compilationAssets[file_path].source()))))
|
|
content.push({
|
|
name: file_name,
|
|
date: blog_date
|
|
})
|
|
}
|
|
})
|
|
content.sort((x1, x2) => { x1.create_date < x2.create_date })
|
|
compilation.emitAsset(
|
|
this.options.output_file, new webpack.sources.RawSource(JSON.stringify(content)))
|
|
return callback();
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
mode: "none",
|
|
entry: './src/index.jsx',
|
|
module:
|
|
{
|
|
rules: [
|
|
{
|
|
test: /\.jsx$/,
|
|
exclude: /node_modules/,
|
|
use: [{
|
|
loader: "babel-loader",
|
|
options:
|
|
{
|
|
presets: ["@babel/preset-env"],
|
|
plugins: [
|
|
["babel-plugin-inferno",
|
|
{
|
|
"imports": true
|
|
}]
|
|
]
|
|
}
|
|
}]
|
|
},
|
|
{
|
|
test: /src.*\.s[ac]ss$/,
|
|
use: ['style-loader', 'css-loader', 'sass-loader']
|
|
},
|
|
{
|
|
test: /src.*\.css$/,
|
|
use: ['style-loader', 'css-loader']
|
|
},
|
|
{
|
|
test: /\.svg$/,
|
|
type: "asset/inline"
|
|
}
|
|
]
|
|
},
|
|
plugins: [
|
|
new BlogListingPlugin(),
|
|
new CopyPlugin({
|
|
patterns: [
|
|
{from: 'index.html'},
|
|
{from: 'robot.txt'},
|
|
{from: 'src/lang', to: 'lang'},
|
|
{from: 'assets/blog', to: 'blog'},
|
|
{from: 'assets/icons', to: 'assets/icons'},
|
|
{from: 'assets/images', to: 'assets/images'},
|
|
{from: 'assets/theme', to: 'assets/theme'}
|
|
]}),
|
|
// new CompressionPlugin(
|
|
// {
|
|
// filename: "[path].gz[query]",
|
|
// algorithm: "gzip",
|
|
// test: [/\.js/, /\.svg/],
|
|
// threshold: 1000
|
|
// })
|
|
],
|
|
output:
|
|
{
|
|
filename: 'bundle.js',
|
|
path: path.resolve(__dirname, 'public'),
|
|
assetModuleFilename: 'assets/[query].[ext]',
|
|
clean: true
|
|
}
|
|
};
|