mirror of
https://github.com/wassname/chatGPTBox.git
synced 2026-06-27 21:36:40 +08:00
358 lines
9.4 KiB
JavaScript
358 lines
9.4 KiB
JavaScript
import archiver from 'archiver'
|
|
import fs from 'fs-extra'
|
|
import path from 'path'
|
|
import webpack from 'webpack'
|
|
import ProgressBarPlugin from 'progress-bar-webpack-plugin'
|
|
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'
|
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
|
import TerserPlugin from 'terser-webpack-plugin'
|
|
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
|
|
|
|
const outdir = 'build'
|
|
|
|
const __dirname = path.resolve()
|
|
const isProduction = process.argv[2] !== '--development' // --production and --analyze are both production
|
|
const isAnalyzing = process.argv[2] === '--analyze'
|
|
|
|
async function deleteOldDir() {
|
|
await fs.rm(outdir, { recursive: true, force: true })
|
|
}
|
|
|
|
async function runWebpack(isWithoutKatex, isWithoutTiktoken, minimal, callback) {
|
|
const shared = [
|
|
'preact',
|
|
'webextension-polyfill',
|
|
'@primer/octicons-react',
|
|
'react-bootstrap-icons',
|
|
'countries-list',
|
|
'i18next',
|
|
'react-i18next',
|
|
'react-tabs',
|
|
'./src/utils',
|
|
'./src/_locales/i18n-react',
|
|
]
|
|
if (isWithoutKatex) shared.push('./src/components')
|
|
|
|
const compiler = webpack({
|
|
entry: {
|
|
'content-script': {
|
|
import: './src/content-script/index.jsx',
|
|
dependOn: 'shared',
|
|
},
|
|
background: {
|
|
import: './src/background/index.mjs',
|
|
},
|
|
popup: {
|
|
import: './src/popup/index.jsx',
|
|
dependOn: 'shared',
|
|
},
|
|
IndependentPanel: {
|
|
import: './src/pages/IndependentPanel/index.jsx',
|
|
dependOn: 'shared',
|
|
},
|
|
shared: shared,
|
|
},
|
|
output: {
|
|
filename: '[name].js',
|
|
path: path.resolve(__dirname, outdir),
|
|
},
|
|
mode: isProduction ? 'production' : 'development',
|
|
devtool: isProduction ? false : 'inline-source-map',
|
|
optimization: {
|
|
minimizer: [
|
|
new TerserPlugin({
|
|
terserOptions: {
|
|
output: { ascii_only: true },
|
|
},
|
|
}),
|
|
new CssMinimizerPlugin(),
|
|
],
|
|
concatenateModules: !isAnalyzing,
|
|
},
|
|
plugins: [
|
|
minimal
|
|
? new webpack.ProvidePlugin({
|
|
Buffer: ['buffer', 'Buffer'],
|
|
})
|
|
: new webpack.ProvidePlugin({
|
|
process: 'process/browser.js',
|
|
Buffer: ['buffer', 'Buffer'],
|
|
}),
|
|
new ProgressBarPlugin({
|
|
format: ' build [:bar] :percent (:elapsed seconds)',
|
|
clear: false,
|
|
}),
|
|
new MiniCssExtractPlugin({
|
|
filename: '[name].css',
|
|
}),
|
|
new BundleAnalyzerPlugin({
|
|
analyzerMode: isAnalyzing ? 'static' : 'disable',
|
|
}),
|
|
...(isWithoutKatex
|
|
? [
|
|
new webpack.NormalModuleReplacementPlugin(/markdown\.jsx/, (result) => {
|
|
if (result.request) {
|
|
result.request = result.request.replace(
|
|
'markdown.jsx',
|
|
'markdown-without-katex.jsx',
|
|
)
|
|
}
|
|
}),
|
|
]
|
|
: []),
|
|
],
|
|
resolve: {
|
|
extensions: ['.jsx', '.mjs', '.js'],
|
|
alias: {
|
|
parse5: path.resolve(__dirname, 'node_modules/parse5'),
|
|
...(minimal
|
|
? { buffer: path.resolve(__dirname, 'node_modules/buffer') }
|
|
: {
|
|
util: path.resolve(__dirname, 'node_modules/util'),
|
|
buffer: path.resolve(__dirname, 'node_modules/buffer'),
|
|
stream: 'stream-browserify',
|
|
crypto: 'crypto-browserify',
|
|
}),
|
|
},
|
|
},
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.m?jsx?$/,
|
|
exclude: /(node_modules)/,
|
|
resolve: {
|
|
fullySpecified: false,
|
|
},
|
|
use: [
|
|
{
|
|
loader: 'babel-loader',
|
|
options: {
|
|
presets: [
|
|
'@babel/preset-env',
|
|
{
|
|
plugins: ['@babel/plugin-transform-runtime'],
|
|
},
|
|
],
|
|
plugins: [
|
|
[
|
|
'@babel/plugin-transform-react-jsx',
|
|
{
|
|
runtime: 'automatic',
|
|
importSource: 'preact',
|
|
},
|
|
],
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.s[ac]ss$/,
|
|
use: [
|
|
MiniCssExtractPlugin.loader,
|
|
{
|
|
loader: 'css-loader',
|
|
options: {
|
|
importLoaders: 1,
|
|
},
|
|
},
|
|
{
|
|
loader: 'sass-loader',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.less$/,
|
|
use: [
|
|
MiniCssExtractPlugin.loader,
|
|
{
|
|
loader: 'css-loader',
|
|
options: {
|
|
importLoaders: 1,
|
|
},
|
|
},
|
|
{
|
|
loader: 'less-loader',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.css$/,
|
|
use: [
|
|
MiniCssExtractPlugin.loader,
|
|
{
|
|
loader: 'css-loader',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.(woff|ttf)$/,
|
|
type: 'asset/resource',
|
|
generator: {
|
|
emit: false,
|
|
},
|
|
},
|
|
{
|
|
test: /\.woff2$/,
|
|
type: 'asset/inline',
|
|
},
|
|
{
|
|
test: /\.(jpg|png|svg)$/,
|
|
type: 'asset/inline',
|
|
},
|
|
{
|
|
test: /\.(graphql|gql)$/,
|
|
loader: 'graphql-tag/loader',
|
|
},
|
|
isWithoutTiktoken
|
|
? {
|
|
test: /crop-text\.mjs$/,
|
|
loader: 'string-replace-loader',
|
|
options: {
|
|
multiple: [
|
|
{
|
|
search: "import { encode } from '@nem035/gpt-3-encoder'",
|
|
replace: '',
|
|
},
|
|
{
|
|
search: 'encode(',
|
|
replace: 'String(',
|
|
},
|
|
],
|
|
},
|
|
}
|
|
: {},
|
|
minimal
|
|
? {
|
|
test: /styles\.scss$/,
|
|
loader: 'string-replace-loader',
|
|
options: {
|
|
multiple: [
|
|
{
|
|
search: "@import '../fonts/styles.css';",
|
|
replace: '',
|
|
},
|
|
],
|
|
},
|
|
}
|
|
: {},
|
|
minimal
|
|
? {
|
|
test: /index\.mjs$/,
|
|
loader: 'string-replace-loader',
|
|
options: {
|
|
multiple: [
|
|
{
|
|
search: 'import { generateAnswersWithChatGLMApi }',
|
|
replace: '//',
|
|
},
|
|
{
|
|
search: 'await generateAnswersWithChatGLMApi',
|
|
replace: '//',
|
|
},
|
|
],
|
|
},
|
|
}
|
|
: {},
|
|
],
|
|
},
|
|
})
|
|
if (isProduction) compiler.run(callback)
|
|
else compiler.watch({}, callback)
|
|
}
|
|
|
|
async function zipFolder(dir) {
|
|
const output = fs.createWriteStream(`${dir}.zip`)
|
|
const archive = archiver('zip', {
|
|
zlib: { level: 9 },
|
|
})
|
|
archive.pipe(output)
|
|
archive.directory(dir, false)
|
|
await archive.finalize()
|
|
}
|
|
|
|
async function copyFiles(entryPoints, targetDir) {
|
|
if (!fs.existsSync(targetDir)) await fs.mkdir(targetDir)
|
|
await Promise.all(
|
|
entryPoints.map(async (entryPoint) => {
|
|
await fs.copy(entryPoint.src, `${targetDir}/${entryPoint.dst}`)
|
|
}),
|
|
)
|
|
}
|
|
|
|
async function finishOutput(outputDirSuffix) {
|
|
const commonFiles = [
|
|
{ src: 'src/logo.png', dst: 'logo.png' },
|
|
{ src: 'src/rules.json', dst: 'rules.json' },
|
|
|
|
{ src: 'build/shared.js', dst: 'shared.js' },
|
|
{ src: 'build/content-script.css', dst: 'content-script.css' }, // shared
|
|
|
|
{ src: 'build/content-script.js', dst: 'content-script.js' },
|
|
|
|
{ src: 'build/background.js', dst: 'background.js' },
|
|
|
|
{ src: 'build/popup.js', dst: 'popup.js' },
|
|
{ src: 'build/popup.css', dst: 'popup.css' },
|
|
{ src: 'src/popup/index.html', dst: 'popup.html' },
|
|
|
|
{ src: 'build/IndependentPanel.js', dst: 'IndependentPanel.js' },
|
|
{ src: 'src/pages/IndependentPanel/index.html', dst: 'IndependentPanel.html' },
|
|
]
|
|
|
|
// chromium
|
|
const chromiumOutputDir = `./${outdir}/chromium${outputDirSuffix}`
|
|
await copyFiles(
|
|
[...commonFiles, { src: 'src/manifest.json', dst: 'manifest.json' }],
|
|
chromiumOutputDir,
|
|
)
|
|
if (isProduction) await zipFolder(chromiumOutputDir)
|
|
|
|
// firefox
|
|
const firefoxOutputDir = `./${outdir}/firefox${outputDirSuffix}`
|
|
await copyFiles(
|
|
[...commonFiles, { src: 'src/manifest.v2.json', dst: 'manifest.json' }],
|
|
firefoxOutputDir,
|
|
)
|
|
if (isProduction) await zipFolder(firefoxOutputDir)
|
|
}
|
|
|
|
function generateWebpackCallback(finishOutputFunc) {
|
|
return async function webpackCallback(err, stats) {
|
|
if (err || stats.hasErrors()) {
|
|
console.error(err || stats.toString())
|
|
return
|
|
}
|
|
// console.log(stats.toString())
|
|
|
|
await finishOutputFunc()
|
|
}
|
|
}
|
|
|
|
async function build() {
|
|
await deleteOldDir()
|
|
if (isProduction && !isAnalyzing) {
|
|
// await runWebpack(
|
|
// true,
|
|
// false,
|
|
// generateWebpackCallback(() => finishOutput('-without-katex')),
|
|
// )
|
|
// await new Promise((r) => setTimeout(r, 5000))
|
|
await runWebpack(
|
|
true,
|
|
true,
|
|
true,
|
|
generateWebpackCallback(() => finishOutput('-without-katex-and-tiktoken')),
|
|
)
|
|
await new Promise((r) => setTimeout(r, 10000))
|
|
}
|
|
await runWebpack(
|
|
false,
|
|
false,
|
|
false,
|
|
generateWebpackCallback(() => finishOutput('')),
|
|
)
|
|
}
|
|
|
|
build()
|