├── .browserslistrc ├── .env ├── .eslintrc.js ├── .gitignore ├── README.md ├── babel.config.js ├── chainWebpack.config.js ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── api │ ├── asset.js │ ├── dirscan.js │ ├── dnslog.js │ ├── favicon.js │ ├── fofa.js │ ├── project.js │ └── snippet.js ├── assets │ ├── fofa.ico │ ├── fofa.png │ ├── icon_128.png │ ├── logo.png │ ├── qaxhunter.svg │ ├── quake.png │ ├── shodan.png │ └── zoomeye.png ├── background │ └── index.js ├── components │ ├── BiuAssetInfo.vue │ ├── BiuDNSLog.vue │ ├── DirScan.vue │ ├── FaviconInfo.vue │ ├── FofaHostInfo.vue │ ├── Projects.vue │ ├── Settings.vue │ └── ShortCut.vue ├── contentScripts │ └── index.js ├── manifest.json ├── options │ ├── App.vue │ └── index.js ├── popup │ ├── App.vue │ └── index.js └── utils │ ├── biu.js │ ├── clipboard.js │ ├── datetime.js │ ├── fofa.js │ ├── regex.js │ ├── setting.js │ └── storage.js └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | 2 | # The following environment variables will be associated with the relevant configuration on webpack. 3 | # Deletion and modification may cause the program to crash. 4 | 5 | BACKGROUND_MODE=js -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended' 9 | ], 10 | parserOptions: { 11 | parser: 'babel-eslint' 12 | }, 13 | rules: { 14 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 15 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | node_modules 3 | package-lock.json 4 | .DS_Store 5 | /dist 6 | 7 | 8 | # local env files 9 | .env.local 10 | .env.*.local 11 | 12 | # Log files 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | pnpm-debug.log* 17 | 18 | # Editor directories and files 19 | .idea 20 | .vscode 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [biu浏览器扩展](https://github.com/0xbug/biu-brower-ext) 2 | 3 | 4 | # 如何开发 5 | 6 | 前端使用了 https://arco.design/vue/docs/start 7 | ## 安装Vue CLI 8 | ``` 9 | npm install -g @vue/cli 10 | ``` 11 | 12 | ## 安装依赖 13 | ``` 14 | npm install 15 | ``` 16 | 17 | ### 开发模式,然后浏览器加载dist目录 18 | ``` 19 | npm run serve 20 | ``` 21 | 22 | ### 构建 23 | ``` 24 | npm run build 25 | ``` 26 | 27 | ### Lints and fixes files 28 | ``` 29 | npm run lint 30 | ``` -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /chainWebpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 3 | const ExtensionReloader = require('webpack-extension-reloader'); 4 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 5 | 6 | const isDevMode = process.env.NODE_ENV === 'development' 7 | const backgroundMode = process.env.BACKGROUND_MODE; 8 | 9 | const chainWebpack = config => { 10 | if (backgroundMode === 'js') { 11 | config.entry('background').add(path.resolve(__dirname, './src/background/index.js')); 12 | } 13 | config.entry('contentScripts').add(path.resolve(__dirname, './src/contentScripts/index.js')); 14 | config.output.filename('[name].js'); 15 | config.plugins.delete('copy'); 16 | 17 | config.plugin('CopyWebpackPlugin').use(CopyWebpackPlugin, [[ 18 | { from: 'src/assets', to: 'assets' }, 19 | { from: 'src/manifest.json', to: 'manifest.json', flatten: true }, 20 | ]]); 21 | 22 | if (isDevMode) { 23 | // development-mode 24 | config.plugin('ExtensionReloader').use(ExtensionReloader, [{ 25 | contentScript: 'contentScripts', 26 | background: 'background', 27 | extensionPage: 'popup', 28 | options: 'options', 29 | }]); 30 | 31 | config.plugin('CleanWebpackPlugin').use(CleanWebpackPlugin, [{ 32 | cleanAfterEveryBuildPatterns: ['*hot-update*'], 33 | cleanStaleWebpackAssets: false, 34 | }]); 35 | } 36 | 37 | config.optimization.clear(); 38 | } 39 | 40 | module.exports = chainWebpack; 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "biu-browser-ext", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^3.6.5", 12 | "vue": "^3.0.0" 13 | }, 14 | "devDependencies": { 15 | "@arco-design/web-vue": "^2.13.0", 16 | "@vue/cli-plugin-babel": "~4.5.0", 17 | "@vue/cli-plugin-eslint": "~4.5.0", 18 | "@vue/cli-service": "~4.5.0", 19 | "@vue/compiler-sfc": "^3.0.0", 20 | "axios": "^0.24.0", 21 | "babel-eslint": "^10.1.0", 22 | "cheerio": "^1.0.0-rc.10", 23 | "clean-webpack-plugin": "^3.0.0", 24 | "copy-to-clipboard": "^3.3.1", 25 | "dayjs": "^1.10.7", 26 | "eslint": "^6.7.2", 27 | "eslint-plugin-vue": "^7.0.0", 28 | "urijs": "^1.19.7", 29 | "web-storage-cache": "^1.1.1", 30 | "webpack-extension-reloader": "^1.1.4" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/api/asset.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import {getApiKey,getBaseUrl} from "@/utils/biu"; 3 | 4 | export const getAssetInfo = (params) => { 5 | return axios.request({ 6 | url: getBaseUrl() + "/api/asset/search", 7 | params, 8 | headers: { 9 | 'Biu-Api-Key': getApiKey() 10 | }, 11 | method: "get" 12 | }); 13 | }; -------------------------------------------------------------------------------- /src/api/dirscan.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export const getHTTPResponse = (url, method = "get") => { 4 | return axios.request({ 5 | url: url, 6 | method: method 7 | }); 8 | }; -------------------------------------------------------------------------------- /src/api/dnslog.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import {getApiKey,getBaseUrl} from "@/utils/biu"; 3 | 4 | export const getRecords = (params) => { 5 | return axios.request({ 6 | url: getBaseUrl() + "/api/dnslog", 7 | params, 8 | headers: { 9 | 'Biu-Api-Key': getApiKey() 10 | }, 11 | method: "get" 12 | }); 13 | }; -------------------------------------------------------------------------------- /src/api/favicon.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import {getApiKey, getBaseUrl} from "@/utils/biu"; 3 | 4 | export const getFaviconHash = (favIconUrl) => { 5 | return axios.request({ 6 | url: favIconUrl, 7 | responseType: 'blob', 8 | method: "get" 9 | }).then(res => { 10 | let content = new File([res.data], "file"); 11 | let formData = new FormData(); 12 | formData.append("file", content); 13 | return axios.request({ 14 | url: getBaseUrl() + "/api/favicon/upload/search", 15 | data: formData, 16 | headers: { 17 | 'Content-Type': 'multipart/form-data', 18 | 'Biu-Api-Key': getApiKey() 19 | }, 20 | method: 'post' 21 | }); 22 | }) 23 | 24 | 25 | } 26 | ; -------------------------------------------------------------------------------- /src/api/fofa.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import {getAuthorization, getApiHost,getWebHost} from "@/utils/fofa"; 3 | 4 | export const getHostInfo = (host) => { 5 | return axios.request({ 6 | url: "https://" + getWebHost() + "/hosts/" + host, 7 | method: "get" 8 | }); 9 | }; 10 | export const getHostComponentsInfo = (host) => { 11 | 12 | return axios.request({ 13 | url: "https://" + getApiHost() + "/v1/host/" + host, 14 | headers: {'Authorization': getAuthorization()}, 15 | method: "get" 16 | }); 17 | }; -------------------------------------------------------------------------------- /src/api/project.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import {getApiKey,getBaseUrl} from "@/utils/biu"; 3 | 4 | export const getProjects = (params) => { 5 | return axios.request({ 6 | url: getBaseUrl() + "/api/project", 7 | params, 8 | headers: { 9 | 'Biu-Api-Key': getApiKey() 10 | }, 11 | method: "get" 12 | }); 13 | }; 14 | export const updateProject = (data) => { 15 | return axios.request({ 16 | url: getBaseUrl() + "/api/project/optimize", 17 | data, 18 | headers: { 19 | 'Biu-Api-Key': getApiKey() 20 | }, 21 | method: "patch" 22 | }); 23 | }; -------------------------------------------------------------------------------- /src/api/snippet.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import {getApiKey,getBaseUrl} from "@/utils/biu"; 3 | 4 | export const addSnippet = (data) => { 5 | return axios.request({ 6 | url: getBaseUrl() + "/api/snippet", 7 | data, 8 | headers: { 9 | 'Biu-Api-Key': getApiKey() 10 | }, 11 | method: "post" 12 | }); 13 | }; -------------------------------------------------------------------------------- /src/assets/fofa.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/assets/fofa.ico -------------------------------------------------------------------------------- /src/assets/fofa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/assets/fofa.png -------------------------------------------------------------------------------- /src/assets/icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/assets/icon_128.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/qaxhunter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Group 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/assets/quake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/assets/quake.png -------------------------------------------------------------------------------- /src/assets/shodan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/assets/shodan.png -------------------------------------------------------------------------------- /src/assets/zoomeye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/assets/zoomeye.png -------------------------------------------------------------------------------- /src/background/index.js: -------------------------------------------------------------------------------- 1 | import {getBaseUrl} from "@/utils/biu"; 2 | import {addSnippet} from '@/api/snippet'; 3 | import {getWebHost} from "@/utils/fofa"; 4 | 5 | 6 | chrome.contextMenus.create({ // eslint-disable-line 7 | title: '新增Biu笔记:%s', 8 | contexts: ['selection'], 9 | onclick: function (params) { 10 | addSnippet({ 11 | "target": "", 12 | "content": "```\n" + params.selectionText + "\n```", 13 | "source": null, 14 | "tags": [], 15 | "public": false 16 | }) 17 | } 18 | }) 19 | chrome.contextMenus.create({ // eslint-disable-line 20 | title: 'Biu查看资产:%s', 21 | contexts: ['selection'], 22 | onclick: function (params) { 23 | chrome.tabs.create({url: getBaseUrl() + '/assets/detail/' + params.selectionText}); // eslint-disable-line 24 | } 25 | }); 26 | chrome.contextMenus.create({ // eslint-disable-line 27 | title: 'Biu搜索:%s', 28 | contexts: ['selection'], 29 | onclick: function (params) { 30 | chrome.tabs.create({url: getBaseUrl() + '/assets/port?keyword=' + params.selectionText}); // eslint-disable-line 31 | } 32 | }); 33 | chrome.contextMenus.create({ // eslint-disable-line 34 | title: 'Biu资产助手搜索:%s', 35 | contexts: ['selection'], 36 | onclick: function (params) { 37 | chrome.tabs.create({url: getBaseUrl() + '/vis?keywords=' + params.selectionText}); // eslint-disable-line 38 | } 39 | }); 40 | chrome.contextMenus.create({ // eslint-disable-line 41 | title: 'Fofa搜索:%s', 42 | contexts: ['selection'], 43 | onclick: function (params) { 44 | chrome.tabs.create({url: 'https://'+getWebHost()+'/result?q=' + params.selectionText}); // eslint-disable-line 45 | } 46 | }); 47 | chrome.contextMenus.create({ // eslint-disable-line 48 | title: 'QAX Hunter搜索:%s', 49 | contexts: ['selection'], 50 | onclick: function (params) { 51 | chrome.tabs.create({url: 'https://hunter.qianxin.com/home/list?searchType=grammar&search=' + params.selectionText}); // eslint-disable-line 52 | } 53 | }); 54 | chrome.contextMenus.create({ // eslint-disable-line 55 | title: 'Quake搜索:%s', 56 | contexts: ['selection'], 57 | onclick: function (params) { 58 | chrome.tabs.create({url: 'https://quake.360.cn/quake/#/searchResult?searchVal=' + params.selectionText}); // eslint-disable-line 59 | } 60 | }); 61 | chrome.contextMenus.create({ // eslint-disable-line 62 | title: 'ZoomEye搜索:%s', 63 | contexts: ['selection'], 64 | onclick: function (params) { 65 | chrome.tabs.create({url: 'https://www.zoomeye.org/searchResult?q=' + params.selectionText}); // eslint-disable-line 66 | } 67 | }); 68 | 69 | chrome.contextMenus.create({ // eslint-disable-line 70 | title: '微步IP搜索:%s', 71 | contexts: ['selection'], 72 | onclick: function (params) { 73 | chrome.tabs.create({url: 'https://x.threatbook.cn/v5/ip/' + params.selectionText}); // eslint-disable-line 74 | } 75 | }); 76 | 77 | chrome.contextMenus.create({ // eslint-disable-line 78 | title: '微步域名搜索:%s', 79 | contexts: ['selection'], 80 | onclick: function (params) { 81 | chrome.tabs.create({url: 'https://x.threatbook.cn/v5/domain/' + params.selectionText}); // eslint-disable-line 82 | } 83 | }); -------------------------------------------------------------------------------- /src/components/BiuAssetInfo.vue: -------------------------------------------------------------------------------- 1 | 147 | 148 | 195 | 196 | 197 | 203 | -------------------------------------------------------------------------------- /src/components/BiuDNSLog.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 97 | 98 | 99 | 105 | -------------------------------------------------------------------------------- /src/components/DirScan.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 150 | 151 | 152 | 158 | -------------------------------------------------------------------------------- /src/components/FaviconInfo.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 71 | 72 | -------------------------------------------------------------------------------- /src/components/FofaHostInfo.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 111 | 112 | -------------------------------------------------------------------------------- /src/components/Projects.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 73 | 74 | 75 | 81 | -------------------------------------------------------------------------------- /src/components/Settings.vue: -------------------------------------------------------------------------------- 1 | 74 | 75 | 141 | 142 | -------------------------------------------------------------------------------- /src/components/ShortCut.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 76 | 77 | -------------------------------------------------------------------------------- /src/contentScripts/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/contentScripts/index.js -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser_action": { 3 | "default_popup": "./popup.html" 4 | }, 5 | "content_scripts": [ 6 | { 7 | "all_frames": false, 8 | "js": [ 9 | "./contentScripts.js" 10 | ], 11 | "matches": [ 12 | "http://*/*", 13 | "https://*/*" 14 | ], 15 | "run_at": "document_start" 16 | } 17 | ], 18 | "icons": { 19 | "16": "assets/logo.png", 20 | "32": "assets/logo.png", 21 | "64": "assets/logo.png", 22 | "128": "assets/logo.png" 23 | }, 24 | "manifest_version": 2, 25 | "options_ui": { 26 | "chrome_style": true, 27 | "page": "./options.html" 28 | }, 29 | "permissions": [ 30 | "contextMenus", 31 | "tabs", 32 | "notifications", 33 | "webRequest", 34 | "webRequestBlocking", 35 | "storage", 36 | "http://*/*", 37 | "https://*/*" 38 | ], 39 | "web_accessible_resources":[], 40 | "version": "1.1.1", 41 | "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", 42 | "background": { 43 | "scripts": [ 44 | "./background.js" 45 | ] 46 | }, 47 | "description": "Biu 浏览器插件", 48 | "name": "Biu" 49 | } 50 | -------------------------------------------------------------------------------- /src/options/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | 14 | 24 | -------------------------------------------------------------------------------- /src/options/index.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app'); 5 | -------------------------------------------------------------------------------- /src/popup/App.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 92 | 93 | 95 | -------------------------------------------------------------------------------- /src/popup/index.js: -------------------------------------------------------------------------------- 1 | import {createApp} from 'vue' 2 | import {getTsTime} from '@/utils/datetime'; 3 | import {copyText} from '@/utils/clipboard'; 4 | import ArcoVue from '@arco-design/web-vue'; 5 | import ArcoVueIcon from '@arco-design/web-vue/es/icon'; 6 | import App from './App.vue'; 7 | import '@arco-design/web-vue/dist/arco.css'; 8 | 9 | 10 | const app = createApp(App); 11 | app.use(ArcoVue); 12 | app.use(ArcoVueIcon); 13 | app.config.productionTip = false; 14 | app.config.globalProperties.copy = copyText; // eslint-disable-line 15 | app.config.globalProperties.getTsTime = getTsTime; // eslint-disable-line 16 | app.config.globalProperties.chrome = chrome; // eslint-disable-line 17 | app.mount('#app'); 18 | -------------------------------------------------------------------------------- /src/utils/biu.js: -------------------------------------------------------------------------------- 1 | import {getSetting, setSetting} from "@/utils/setting"; 2 | 3 | export const getApiKey = () => getSetting("apiKey"); 4 | export const getBaseUrl = () => getSetting("baseUrl"); 5 | 6 | export const setBaseUrl = url => { 7 | setSetting('baseUrl', url) 8 | } 9 | export const setApiKey = ak => { 10 | setSetting('apiKey', ak) 11 | } -------------------------------------------------------------------------------- /src/utils/clipboard.js: -------------------------------------------------------------------------------- 1 | import copy from 'copy-to-clipboard'; 2 | 3 | export const copyText = (text) => { 4 | copy(text); 5 | } -------------------------------------------------------------------------------- /src/utils/datetime.js: -------------------------------------------------------------------------------- 1 | import dayjs from "dayjs"; 2 | 3 | export const getTsTime = (ts) => { 4 | return dayjs.unix(ts).format('YYYY-MM-DD HH:mm:ss') 5 | }; 6 | 7 | -------------------------------------------------------------------------------- /src/utils/fofa.js: -------------------------------------------------------------------------------- 1 | import {getSetting} from "@/utils/setting"; 2 | 3 | export const getAuthorization = () => getSetting("fofaAuth"); 4 | export const getApiHost = () => getSetting("fofaApiHost"); 5 | export const getWebHost = () => getSetting("fofaWebHost"); -------------------------------------------------------------------------------- /src/utils/regex.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xbug/biu-brower-ext/ba66bfdda9b08b9b5afcb6bc22c47e2789231bb3/src/utils/regex.js -------------------------------------------------------------------------------- /src/utils/setting.js: -------------------------------------------------------------------------------- 1 | import wsCache from "@/utils/storage"; 2 | 3 | export const getSetting = (key) => { 4 | return wsCache.get(key) 5 | }; 6 | 7 | export const setSetting = (key, value) => { 8 | wsCache.set(key, value) 9 | } -------------------------------------------------------------------------------- /src/utils/storage.js: -------------------------------------------------------------------------------- 1 | import WebStorageCache from 'web-storage-cache'; 2 | 3 | let wsCache = new WebStorageCache(); 4 | 5 | export default wsCache -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const chainWebpack = require('./chainWebpack.config.js'); 2 | const backgroundMode = process.env.BACKGROUND_MODE; 3 | const devtoolMode = process.env.DEVTOOL_MODE; 4 | const newtabMode = process.env.NEWTAB_MODE; 5 | 6 | const config = { 7 | devServer: { 8 | writeToDisk: true, 9 | hot: false, 10 | disableHostCheck: true, 11 | }, 12 | filenameHashing: false, 13 | pages: { 14 | options: { 15 | entry: 'src/options/index.js', 16 | template: 'public/index.html', 17 | filename: 'options.html', 18 | title: 'Options', 19 | chunks: ['chunk-vendors', 'chunk-common', 'options'], 20 | }, 21 | popup: { 22 | entry: 'src/popup/index.js', 23 | template: 'public/index.html', 24 | filename: 'popup.html', 25 | title: 'Popup', 26 | chunks: ['chunk-vendors', 'chunk-common', 'popup'], 27 | }, 28 | }, 29 | css: { 30 | extract: true, 31 | }, 32 | chainWebpack, 33 | } 34 | 35 | if (backgroundMode === 'html') { 36 | config.pages['background'] = { 37 | entry: 'src/background/index.js', 38 | template: 'public/index.html', 39 | filename: 'background.html', 40 | title: 'Background', 41 | chunks: ['chunk-vendors', 'chunk-common', 'background'], 42 | } 43 | } 44 | 45 | if (devtoolMode) { 46 | config.pages['devtool'] = { 47 | entry: 'src/devtool/index.js', 48 | template: 'public/index.html', 49 | filename: 'devtool.html', 50 | title: 'Devtool', 51 | } 52 | } 53 | 54 | if (newtabMode) { 55 | config.pages['newtab'] = { 56 | entry: 'src/newtab/index.js', 57 | template: 'public/index.html', 58 | filename: 'newtab.html', 59 | title: 'NewTab', 60 | } 61 | } 62 | 63 | module.exports = config; 64 | --------------------------------------------------------------------------------