Browse Source

openai in circles

develop
dskvr 2 years ago
parent
commit
3b5bab3ed8
  1. 1
      css.loaderOptions.sass
  2. 4
      package.json
  3. 12
      postcss.config.js
  4. 0
      src/components/TaskManager.vue
  5. 43
      src/components/relays/ListClearnet.vue
  6. 9
      src/components/relays/RefreshComponent.vue
  7. 6
      src/components/relays/SingleClearnet.vue
  8. 0
      src/components/relays/TaskQueue.vue
  9. 69
      src/components/relays/ToolFilter.vue
  10. 13
      src/store/index.js
  11. 47
      src/store/tasks.js
  12. 621
      src/styles/main.scss
  13. 3
      tailwind.config.js
  14. 75
      vue.config.js
  15. 63
      webpack.config.js

1
css.loaderOptions.sass

@ -0,0 +1 @@
css.loaderOptions.sass

4
package.json

@ -38,6 +38,8 @@
"onion-regex": "2.0.8",
"pinia": "2.0.28",
"pinia-plugin-persistedstate-2": "2.0.8",
"pinia-shared-state": "0.2.10",
"postcss-apply": "0.12.0",
"requests": "0.3.0",
"socks-proxy-agent": "7.0.0",
"stream-browserify": "3.0.0",
@ -70,7 +72,9 @@
"json-server": "0.17.1",
"mini-css-extract-plugin": "2.7.2",
"node-polyfill-webpack-plugin": "2.0.1",
"node-sass": "8.0.0",
"postcss": "8.4.20",
"postcss-loader": "7.0.2",
"postcss-preset-env": "7.8.3",
"sass": "1.56.1",
"sass-loader": "13.2.0",

12
postcss.config.js

@ -1,6 +1,8 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
require('postcss-apply')
]
}

0
src/components/TaskManager.vue

43
src/components/relays/ListClearnet.vue

@ -41,7 +41,7 @@
</tr>
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
<tr v-for="(relay, index) in subsectionRelays" :key="relay" class="bg-gray-50 hover:bg-slate-200" :class="getResultClass(relay, index)">
<tr v-for="(relay, index) in subsectionRelays" :key="relay" :class="getResultClass(relay, index)">
<td class="status-indicator" :key="generateKey(relay, 'aggregate')">
<span :class="results[relay]?.aggregate" class="aggregate indicator">
<span></span>
@ -64,17 +64,26 @@
<td class="latency text-center">
<span>{{ results[relay]?.latency?.final }}<span v-if="results[relay]?.check?.latency">ms</span></span>
</td>
<!-- .indicator {
display:block;
margin: 0 auto;
height: 14px;
width: 14px;
border-radius: 7px;
border-width:0px;
} -->
<td class="connect text-center" :key="generateKey(relay, 'check.connect')">
<span :class="getIndicatorClass(relay, 'connect')"></span>
<span :class="getIndicatorClass(relay, 'connect')" class="indicator"></span>
</td>
<td class="read text-center" :key="generateKey(relay, 'check.read')">
<span :class="getIndicatorClass(relay, 'read')"></span>
<span :class="getIndicatorClass(relay, 'read')" class="indicator"></span>
</td>
<td class="write text-center" :key="generateKey(relay, 'check.write')">
<span :class="getIndicatorClass(relay, 'write')"></span>
<span :class="getIndicatorClass(relay, 'write')" class="indicator"></span>
</td>
<td class="fav text-center" :key="generateKey(relay, 'check.write')">
@ -186,6 +195,8 @@
return {
loaded: this.results[relay]?.state == 'complete',
'bg-slate-100': index % 2,
'bg-red-50 hover:bg-red-100': this.store.relays.isFavorite(relay),
'bg-gray-50 hover:bg-slate-200': !this.store.relays.isFavorite(relay),
}
}
},
@ -194,13 +205,15 @@
},
getIndicatorClass(){
return (relay, key) => {
let cl = this.results[relay]?.check?.[key] === true
? 'success'
: this.results[relay]?.check?.[key] === false
? 'failure'
: 'pending'
return `indicator ${cl}`
}
return {
// 'bg-green-500': this.results[relay]?.check?.[key] !== false,
// 'bg-red-500': this.results[relay]?.check?.[key] === false,
// 'bg-gray-500': 'undefined' === typeof this.results[relay]?.check?.[key]
'success': this.results[relay]?.check?.[key] !== false,
'failure': this.results[relay]?.check?.[key] === false,
'pending': 'undefined' === typeof this.results[relay]?.check?.[key]
}
}
},
generateKey(){
return (url, key) => crypto.createHash('md5').update(`${url}_${key}`).digest('hex')
@ -243,8 +256,16 @@
methods: Object.assign(RelaysLib, localMethods),
})
</script>
<style lang=postcss>
.indicator {
@apply h-4 w-4 block rounded-lg
}
</style>
<style lang='css' scoped>
table {
border-collapse: collapse !important;
}

9
src/components/relays/RefreshComponent.vue

@ -40,7 +40,7 @@ const localMethods = {
setRefreshInterval: function(){
clearInterval(this.interval)
this.interval = setInterval(() => {
if(!this.store.prefs.refresh || !this.windowActive )
if(!this.store.prefs.refresh )
return
this.untilNext = this.timeUntilRefresh()
@ -51,7 +51,6 @@ const localMethods = {
}, 1000)
},
refreshNow(){
this.disabled = true
this.invalidate(true)
},
handleVisibility(){
@ -181,15 +180,13 @@ export default defineComponent({
},
unmounted(){
clearInterval(this.interval)
// document.removeEventListener("visibilitychange", this.handleVisibility, false);
},
beforeMount(){
this.untilNext = this.timeUntilRefresh()
this.sinceLast = this.timeSinceRefresh()
},
mounted(){
if(!this.windowActive)
return
this.relays = this.store.relays.getAll
this.lastUpdate = this.store.relays.lastUpdate
@ -202,7 +199,6 @@ export default defineComponent({
},
updated(){},
computed: Object.assign(SharedComputed, {
getDynamicTimeout: function(){
return this.averageLatency*this.relays.length
},
@ -225,7 +221,6 @@ export default defineComponent({
lastUpdate: null,
sinceLast: null,
interval: null,
disabled: true,
windowActive: true,
averageLatency: 200
}

6
src/components/relays/SingleClearnet.vue

@ -24,15 +24,15 @@
</td>
<td class="connect text-center" :key="generateKey(relay, 'check.connect')">
<span :class="getIndicatorClass(relay, 'connect')"></span>
<span :class="getIndicatorClass(relay, 'connect')">Connect</span>
</td>
<td class="read text-center" :key="generateKey(relay, 'check.read')">
<span :class="getIndicatorClass(relay, 'read')"></span>
<span :class="getIndicatorClass(relay, 'read')">Read</span>
</td>
<td class="write text-center" :key="generateKey(relay, 'check.write')">
<span :class="getIndicatorClass(relay, 'write')"></span>
<span :class="getIndicatorClass(relay, 'write')">write</span>
</td>
<td class="fav text-center" :key="generateKey(relay, 'check.write')">

0
src/components/relays/TaskQueue.vue

69
src/components/relays/ToolFilter.vue

@ -0,0 +1,69 @@
<template>
<div class="w-full max-w-lg lg:max-w-xs">
<label for="relay-filter" class="sr-only">Filter Relays</label>
<div class="relative">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
<MagnifyingGlassIcon class="h-5 w-5 text-gray-400" aria-hidden="true" />
</div>
<input
id="relay-filter"
name="relay-filter"
placeholder="Filter Relays" type="search"
class="block w-full rounded-md border border-gray-300 bg-white py-2 pl-10 pr-3 leading-5 placeholder-gray-500 focus:border-indigo-500 focus:placeholder-gray-400 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm"
/>
</div>
</div>
</template>
<script>
//vue
import { defineComponent } from 'vue'
//pinia
import { setupStore } from '@/store'
//shared methods
import RelaysLib from '@/shared/relays-lib.js'
//theme
import { MagnifyingGlassIcon } from '@heroicons/vue/20/solid'
const localMethods = {
toggle() {
this.isActive = !this.isActive;
},
clearData(){
this.store.relays.clearResults()
}
}
export default defineComponent({
name: 'ToolFilter',
components: {
MagnifyingGlassIcon
},
setup(){
return {
store : setupStore()
}
},
mounted(){
// this.preferences = this
},
updated(){
// this.setCache('preferences')
},
computed: {},
methods: Object.assign(localMethods, RelaysLib),
props: {},
data() {
return {
storage: null,
refresh: true,
preferences: {
refresh: true,
cacheExpiration: 30*60*1000
},
isActive: false,
}
},
})
</script>

13
src/store/index.js

@ -1,5 +1,6 @@
import { createPinia } from 'pinia'
import { createPersistedStatePlugin } from 'pinia-plugin-persistedstate-2'
import { PiniaSharedState } from 'pinia-shared-state';
import { useRelaysStore } from './relays.js'
import { usePrefsStore } from './prefs.js'
@ -14,6 +15,18 @@ export const plugin = (app) => {
const installPersistedStatePlugin = createPersistedStatePlugin()
pinia.use((context) => installPersistedStatePlugin(context))
// Pass the plugin to your application's pinia plugin
pinia.use(
PiniaSharedState({
// Enables the plugin for all stores. Defaults to true.
enable: true,
// If set to true this tab tries to immediately recover the shared state from another tab. Defaults to true.
initialize: false,
// Enforce a type. One of native, idb, localstorage or node. Defaults to native.
type: 'localstorage',
}),
);
app.use(pinia)
}

47
src/store/tasks.js

@ -2,16 +2,61 @@ import { defineStore } from 'pinia'
export const useTaskStore = defineStore('tasks', {
state: () => ({
//queue
pending: new Array(),
completed: new Array(),
active: new Object(),
//legacy
processing: false,
processedRelays: new Array(),
currentTask: null
}),
getters: {
//legacy
getProcessedRelays: (state) => Array.from(state.processedRelays),
isProcessing: (state) => state.processing,
isRelayProcessed: (state) => (relay) => state.processedRelays.includes(relay)
isRelayProcessed: (state) => (relay) => state.processedRelays.includes(relay),
//queue/lists
getPending: (state) => state.pending,
getActive: (state) => state.active,
getCompleted: (state) => state.completed,
//queue/states
isActive: (state) => Object.keys( state.active ).length > 0,
isIdle: (state) => Object.keys( state.active ).length == 0,
arePending: (state) => state.pending.length > 0,
},
actions: {
//queue
addJob(job){
this.pending.push(job)
if( this.isIdle )
this.startNextJob()
},
startNextJob(){
if( this.isActive )
this.completed.push(this.active)
if( this.arePending ) {
this.active = this.pending[0]
this.pending.shift()
}
else {
this.active = {}
}
},
clearJobs(type){
this[type] = new Array()
},
cancelJob( id ){
const index = this.pending.findIndex( job => job.id === id )
this.removeJob( index )
},
removeJob( index ){
this.pending.splice( index, 1 )
},
//legacy
addProcessedRelay(relay){
if(!this.processedRelays.includes(relay))
this.processedRelays.push(relay)

621
src/styles/main.scss

@ -4,332 +4,329 @@
@tailwind utilities;
td ul { padding:0; margin:0; list-style: none; }
td ul li { list-style: none; }
.q-tabs {
border-bottom: 1px solid var(--q-accent)
}
table {
width:100%;
}
.left-align {
text-align:left;
}
tr.relay td {
font-style: italic;
opacity: 0.5;
}
tr.relay.loaded td {
font-style: normal;
opacity: 1;
}
.indicator {
display:block;
margin: 0 auto;
height: 14px;
width: 14px;
border-radius: 7px;
border-width:0px;
}
.badge {
height:auto;
width: auto;
display:inline-block;
padding: 2px 5px;
font-size: 15px;
position: relative;
top: -3px;
min-width: 15px;
margin-right:5px;
}
.public .badge,
.offline .badge {
color: white;
}
.public.online .badge {
background:green
}
.restricted.online .badge {
background:orange
}
.offline .badge {
background:red
}
tr.online .indicator.failure {
background-color:orange !important;
}
.aggregate.indicator {
background-color: transparent;
border-radius: 0px;
border-style: solid;
}
.indicator.pending {
background-color: #c0c0c0;
border-color: rgba(55,55,55,0.5);
}
.indicator.success {
background-color: green;
border-color: rgba(0,255,0,0.5);
}
.indicator.failure {
background-color: red;
border-color: rgba(255,0,0,0.5);
}
.indicator.caution {
background-color: orange;
border-color: rgba(255, 191, 0,0.5);
}
.indicator.public {
background-color: green;
border-color: rgba(0,255,0,0.5);
}
.indicator.restricted {
position:relative;
border-color: transparent;
background-color: transparent
}
.indicator.restricted span:first-child {
position:absolute;
width: 0;
height: 0;
border-top: 14px solid green;
border-right: 14px solid transparent;
}
.indicator.restricted span:last-child {
position:absolute;
width: 0;
height: 0;
border-bottom: 14px solid orange;
border-left: 14px solid transparent;
}
//
// td ul { padding:0; margin:0; list-style: none; }
// td ul li { list-style: none; }
// .q-tabs {
// border-bottom: 1px solid var(--q-accent)
// }
// table {
// width:100%;
// }
// .left-align {
// text-align:left;
// }
// tr.relay td {
// font-style: italic;
// opacity: 0.5;
// }
// tr.relay.loaded td {
// font-style: normal;
// opacity: 1;
// }
// // .indicator {
// // display:block;
// // margin: 0 auto;
// // height: 14px;
// // width: 14px;
// // border-radius: 7px;
// // border-width:0px;
// // }
// .badge {
// height:auto;
// width: auto;
// display:inline-block;
// padding: 2px 5px;
// font-size: 15px;
// position: relative;
// top: -3px;
// min-width: 15px;
// margin-right:5px;
// }
// .public .badge,
// .offline .badge {
// color: white;
// }
// .public.online .badge {
// background:green
// }
// .restricted.online .badge {
// background:orange
// }
// .offline .badge {
// background:red
// }
// tr.online .indicator.failure {
// background-color:orange !important;
// }
// .aggregate.indicator {
// background-color: transparent;
// border-radius: 0px;
// border-style: solid;
// }
// .indicator.pending {
// background-color: #c0c0c0;
// border-color: rgba(55,55,55,0.5);
// }
// .indicator.success {
// background-color: green;
// border-color: rgba(0,255,0,0.5);
// }
// .indicator.failure {
// background-color: red;
// border-color: rgba(255,0,0,0.5);
// }
// .indicator.caution {
// background-color: orange;
// border-color: rgba(255, 191, 0,0.5);
// }
// .indicator.public {
// background-color: green;
// border-color: rgba(0,255,0,0.5);
// }
// .indicator.restricted {
// position:relative;
// border-color: transparent;
// background-color: transparent
// }
//
// .indicator.restricted span:first-child {
// position:absolute;
// width: 0;
// height: 0;
// border-bottom: 14px solid orange;
// border-left: 14px solid transparent;
// border-top: 14px solid green;
// border-right: 14px solid transparent;
// }
//
// .indicator.restricted span:last-child {
// position:absolute;
// width: 0;
// height: 0;
// border-top: 14px solid green;
// border-right: 14px solid transparent;
// border-bottom: 14px solid orange;
// border-left: 14px solid transparent;
// }
.indicator.offline {
background-color: red;
border-color: rgba(255,0,0,0.5);
}
tr.online .relay-url {
cursor: pointer;
}
.verified-shape-wrapper {
display:inline-block;
width: 16px;
height: 16px;
}
.shape.verified {
background: #777;
width: 16px;
height: 16px;
position: relative;
top: 5px;
left:-5px;
text-align: center;
}
th .shape.verified:before,
th .shape.verified:after {
background:#c0c0c0 !important;
}
.shape.verified:before,
.shape.verified:after {
content: "";
position: absolute;
top: 0;
left: 0;
height: 13px;
width: 13px;
background: #777;
}
.shape.verified:before {
transform: rotate(30deg);
}
.shape.verified:after {
transform: rotate(75deg);
}
.credit {
display:inline-block;
color:#333;
text-transform: lowercase;
font-size:12px;
margin-top:25px;
}
.credit a {
text-decoration:none;
}
// #wrapper {
// max-width:1400px;
// margin:0 auto;
// }
div.block {
display:block;
margin:40px 0;
}
h1 {
position:relative;
display:inline-block;
margin: 0 auto
}
h1 sup {
color: #c0c0c0;
font-size:15px;
position:absolute;
right: -45px;
top:15px;
}
.title-card {
text-align:center;
}
.title-card h1 {
font-size:4.5em;
text-align:center;
}
.row {
-webkit-box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
-moz-box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
}
.title-info-card {
border-radius: 20px;
text-align:center;
}
.title-info-card span {
display:inline-block;
margin-top:0.80em;
font-size: 4em;
letter-spacing: -0.1em;
text-align:right;
}
.processing-card {
margin: 0.8em 0;
display:block;
margin:1.5em 0;
font-size: 4em;
letter-spacing: -0.1em;
text-align:center;
}
.loading {
animation-duration: 1.8s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(to right, #fafafa 8%, #f4f4f4 38%, #fafafa 54%);
background-size: 1000px 640px;
position: relative
}
.loaded .loading {
animation: none;
bakground:none;
display:none;
}
@keyframes placeHolderShimmer{
0%{
background-position: -468px 0
}
100%{
background-position: 468px 0
}
}
li.observation {
display: inline;
cursor: pointer;
}
tr.offline .verified, tr.offline .verified *,
tr.offline .latency,
tr.offline .nip,
tr.offline .location {
visibility: hidden;
}
@media only screen and (min-device-width: 640px)
and (max-device-width: 480px)
and (orientation: portrait) {
table .latency,
table .verified,
table .nip {
display: none;
}
}
@media only screen and (min-device-width: 640px)
and (max-device-width: 480px)
and (orientation: landscape) {
table .nip {
display: none;
}
}
// //
// // .indicator.restricted {
// // position:relative;
// // border-color: transparent;
// // background-color: transparent
// // }
// //
// // .indicator.restricted span:first-child {
// // position:absolute;
// // width: 0;
// // height: 0;
// // border-bottom: 14px solid orange;
// // border-left: 14px solid transparent;
// // }
// //
// // .indicator.restricted span:last-child {
// // position:absolute;
// // width: 0;
// // height: 0;
// // border-top: 14px solid green;
// // border-right: 14px solid transparent;
// // }
// .indicator.offline {
// background-color: red;
// border-color: rgba(255,0,0,0.5);
// }
// tr.online .relay-url {
// cursor: pointer;
// }
// .verified-shape-wrapper {
// display:inline-block;
// width: 16px;
// height: 16px;
// }
// .shape.verified {
// background: #777;
// width: 16px;
// height: 16px;
// position: relative;
// top: 5px;
// left:-5px;
// text-align: center;
// }
// th .shape.verified:before,
// th .shape.verified:after {
// background:#c0c0c0 !important;
// }
// .shape.verified:before,
// .shape.verified:after {
// content: "";
// position: absolute;
// top: 0;
// left: 0;
// height: 13px;
// width: 13px;
// background: #777;
// }
// .shape.verified:before {
// transform: rotate(30deg);
// }
// .shape.verified:after {
// transform: rotate(75deg);
// }
// .credit {
// display:inline-block;
// color:#333;
// text-transform: lowercase;
// font-size:12px;
// margin-top:25px;
// }
// .credit a {
// text-decoration:none;
// }
// // #wrapper {
// // max-width:1400px;
// // margin:0 auto;
// // }
// div.block {
// display:block;
// margin:40px 0;
// }
// h1 {
// position:relative;
// display:inline-block;
// margin: 0 auto
// }
// h1 sup {
// color: #c0c0c0;
// font-size:15px;
// position:absolute;
// right: -45px;
// top:15px;
// }
// .title-card {
// text-align:center;
// }
// .title-card h1 {
// font-size:4.5em;
// text-align:center;
// }
// .row {
// -webkit-box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
// -moz-box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
// box-shadow: 0px 1px 32px 4px rgba(0,0,0,0.16);
// }
// .title-info-card {
// border-radius: 20px;
// text-align:center;
// }
// .title-info-card span {
// display:inline-block;
// margin-top:0.80em;
// font-size: 4em;
// letter-spacing: -0.1em;
// text-align:right;
// }
// .processing-card {
// margin: 0.8em 0;
// display:block;
// margin:1.5em 0;
// font-size: 4em;
// letter-spacing: -0.1em;
// text-align:center;
// }
// .loading {
// animation-duration: 1.8s;
// animation-fill-mode: forwards;
// animation-iteration-count: infinite;
// animation-name: placeHolderShimmer;
// animation-timing-function: linear;
// background: #f6f7f8;
// background: linear-gradient(to right, #fafafa 8%, #f4f4f4 38%, #fafafa 54%);
// background-size: 1000px 640px;
// position: relative
// }
// .loaded .loading {
// animation: none;
// bakground:none;
// display:none;
// }
// @keyframes placeHolderShimmer{
// 0%{
// background-position: -468px 0
// }
// 100%{
// background-position: 468px 0
// }
// }
// li.observation {
// display: inline;
// cursor: pointer;
// }
// tr.offline .verified, tr.offline .verified *,
// tr.offline .latency,
// tr.offline .nip,
// tr.offline .location {
// visibility: hidden;
// }
// @media only screen and (min-device-width: 640px)
// and (max-device-width: 480px)
// and (orientation: portrait) {
// table .latency,
// table .verified,
// table .nip {
// display: none;
// }
// }
// @media only screen and (min-device-width: 640px)
// and (max-device-width: 480px)
// and (orientation: landscape) {
// table .nip {
// display: none;
// }
// }

3
tailwind.config.js

@ -16,7 +16,8 @@ module.exports = {
extend: {},
},
plugins: [
require('@tailwindcss/forms'),
require('tailwindcss')('./tailwind.config.js'),
require('autoprefixer'),
],
}

75
vue.config.js

@ -1,34 +1,81 @@
const { defineConfig } = require('@vue/cli-service')
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
const autoprefixer = require('autoprefixer');
const tailwindcss = require('tailwindcss');
const path = require('path');
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
port: 8080
},
// css: {
// loaderOptions: {
// // sass: {
// // data: '@import "./src/styles/main.scss";'
// // },
// postcss: {
// config: () => ({
// path: __dirname
// })
// }
// }
// },
configureWebpack: {
plugins: [new NodePolyfillPlugin()],
optimization: {
splitChunks: {
chunks: "all",
},
},
resolve: {
fallback: {
"fs": false,
"tls": false,
"net": false,
"utf-8-validate": false,
"bufferutil": false
"zlib": require.resolve("browserify-zlib"),
"stream": require.resolve("stream-browserify"),
}
},
experiments: {
topLevelAwait: true
},
module: {
rules: [
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
config: path.resolve(__dirname, './postcss.config.js')
}
}
},
// 'sass-loader'
]
}
]
}
},
chainWebpack: config => {
config.plugins.delete('prefetch')
config.plugins.delete('preload')
config.module
.rule('scss')
.test(/\.scss$/)
.use('vue-style-loader')
.loader('vue-style-loader')
.end()
.use('css-loader')
.loader('css-loader')
.end()
.use('postcss-loader')
.loader('postcss-loader')
.options({
postcssOptions: {
config: {
path: __dirname
}
}
})
.end()
.use('sass-loader')
.loader('sass-loader')
.end()
config.module
.rule('yaml')

63
webpack.config.js

@ -0,0 +1,63 @@
// const { VueLoaderPlugin } = require("vue-loader");
// const HtmlWebpackPlugin = require("html-webpack-plugin");
// const path = require("path");
// const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// module.exports = {
// entry: path.join(__dirname, "src/main.js"),
// devtool: "source-map",
// module: {
// rules: [
// {
// test: /\.vue$/,
// loader: "vue-loader",
// },
// {
// test: /\.css$/,
// use: [
// "style-loader",
// {
// loader: MiniCssExtractPlugin.loader,
// options: {
// esModule: false,
// },
// },
// {
// loader: "css-loader",
// options: {
// // 0 => no loaders (default);
// // 1 => postcss-loader;
// // 2 => postcss-loader, sass-loader
// importLoaders: 1,
// },
// },
// "postcss-loader",
// ],
// },
// ],
// },
// plugins: [
// new VueLoaderPlugin(),
// new HtmlWebpackPlugin({
// template: path.resolve(__dirname, "public/index.html"),
// }),
// new MiniCssExtractPlugin(),
// ],
// devServer: {
// open: true,
// devMiddleware: {
// writeToDisk: true,
// },
// static: {
// watch: true,
// },
// },
// optimization: {
// minimizer: [
// // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// "...",
// new CssMinimizerPlugin(),
// ],
// },
// };
Loading…
Cancel
Save