const VueLoaderPlugin = require('vue-loader/lib/plugin') const TerserPlugin = require('terser-webpack-plugin') const webpack = require('webpack') const path = require('path') const get = require('lodash/get') const { cssStyleLoaders, sassStyleLoaders } = require('./loaders/style-loaders') const tsLoader = require('./loaders/ts-loader') const runtimeInfo = require('./compilation-info/runtime') const relativePath = p => path.join(process.cwd(), p) const getDefaultConfig = (srcFolder) => { const src = srcFolder || relativePath('src') return { mode: 'development', // devtool: 'eval-source-map', watchOptions: { ignored: /node_modules/, }, externals: [ { lodash: 'lodash', }, ], resolve: { extensions: ['.tsx', '.ts', '.js', '.vue', '.json'], alias: { '@': relativePath('src'), 'fuse.js$': 'fuse.js/dist/fuse.basic.esm.min.js', 'vue$': 'vue/dist/vue.esm.js', }, }, performance: { hints: false, }, optimization: { minimizer: [ new TerserPlugin({ terserOptions: { output: { comments: /==\/?UserScript==|^[ ]?@|eslint-disable|spell-checker/i, }, }, extractComments: false, }), ], }, module: { rules: [ { test: /\.(woff2|jpg|png|gif)$/, type: 'asset/inline', include: [src], }, { test: /\.(svg|md)$/, type: 'asset/source', include: [src], }, { test: /\.css$/, use: [ 'style-loader', ...cssStyleLoaders, ], include: /node_modules/, }, { test: /\.css$/, oneOf: [ { resourceQuery: /vue/, use: [ 'style-loader', ...cssStyleLoaders, ], }, { use: [ 'to-string-loader', ...cssStyleLoaders, ], }, ], include: [src], }, { test: /\.scss$/, oneOf: [ { resourceQuery: /vue/, use: [ 'style-loader', ...sassStyleLoaders, ], }, { use: [ 'to-string-loader', ...sassStyleLoaders, ], }, ], include: [src], }, { test: /\.tsx?$/, use: [ ...tsLoader, ], include: [ src, relativePath('tests'), ], }, { test: /\.vue$/, use: [ { loader: 'vue-loader', options: { optimizeSSR: false, hotReload: false, }, }, ], include: [src], }, ], }, plugins: [ new VueLoaderPlugin(), new webpack.ProvidePlugin({ webpackCompilationInfo: [relativePath('webpack/compilation-info'), 'compilationInfo'], }), new webpack.DefinePlugin({ webpackGitInfo: JSON.stringify(require('./compilation-info/git')), }), // new WebpackBar(), new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1, }), // new HardSourcePlugin(), ], cache: { type: "filesystem", buildDependencies: { config: [__filename], } } } } const commonMeta = require('../src/client/common.meta.json') const replaceVariables = text => { return text.replace(/\[([^\[\]]+)\]/g, match => { const value = get(runtimeInfo, match) if (value !== undefined) { return value } return match }) } const getBanner = meta => `// ==UserScript==\n${Object.entries(Object.assign(meta, commonMeta)).map(([key, value]) => { if (Array.isArray(value)) { const lines = [...new Set(value.map(item => `// @${key.padEnd(16, ' ')}${replaceVariables(item)}`))] return lines.join('\n') } return `// @${key.padEnd(16, ' ')}${replaceVariables(value)}` }).join('\n')} // ==/UserScript== /* eslint-disable */ /* spell-checker: disable */ // @[ You can find all source codes in GitHub repo ]` module.exports = { getDefaultConfig, getBanner, }