Очень не хватает мануала, как подключать готовое Vue.js приложение к кастомному интерфейсу BAS.
Весь код, который я видел - это портянка кода Vue.js прямо в интерфейсе, включая и html. Делать так, конечно можно, но как это тестировать хотя бы отдельно приложение Vue.js - вообще не понятно.
Подразумевается, что приложение Vue.js уже есть и оно лежит готовое в папке dist. Необходимо подготовить static хостинг, например https://surge.sh/
Что надо сделать:
- отредактировать vite.config.ts
import { defineConfig, UserConfigExport } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath } from 'url'
import dotenv from 'dotenv'
dotenv.config()
// create .env file with HOSTING_URL=https://yourdomain.com/
const baseUrl = process.env.HOSTING_URL || '/'
// Production build configuration
const productionConfig: Partial<UserConfigExport> = {
plugins: [vue()],
// Base public path when served in development or production. Valid values include:
// Absolute URL pathname, e.g. /foo/
// Full URL, e.g. https://foo.com/
// Empty string or ./ (for embedded deployment)
base: baseUrl,
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
build: {
target: 'chrome78', // Set the target to 'chrome78' since the BAS embedded browser is based on Chromium 78
minify: 'terser', // Enable minification using the 'terser' plugin
terserOptions: {
//compress: { drop_console: true },
//parse: { html5_comments: false }
},
rollupOptions: {
output: {
// Set the output file names for entry, chunk, and assets using a specific format
// https://rollupjs.org/configuration-options/#output-entryfilenames
// Disable hashing of output file names for better performance
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`,
// Inline dynamic imports for better performance
// https://rollupjs.org/configuration-options/#output-inlinedynamicimports
inlineDynamicImports: true
}
}
}
}
// Development build configuration
const developmentConfig: Partial<UserConfigExport> = {
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
}
export default defineConfig({
// Use the productionConfig if NODE_ENV is 'production', otherwise use the developmentConfig
...(process.env.NODE_ENV === 'production' ? productionConfig : developmentConfig)
})
- изменить тип роутинга на createWebHashHistory:
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL), // <<== CHANGE THIS
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/AboutView.vue')
}
]
})
export default router
// eslint-disable-next-line no-undef
if (window.Api === undefined) {
throw new Error('BAS Api is not defined')
}
class BasSettingsClass {
constructor() {
this.baseUrl = 'https://your_domain.surge.sh'
this.username = localStorage.getItem('Username')
this.password = localStorage.getItem('Password')
// Editing file in https://bablosoft.com/bas/editmaininterface/ ?
if (!this.password) {
console.error('Password in localStorage not found')
}
if (!this.username) {
console.error('Username in localStorage not found')
}
}
logCredentials() {
console.log('[auth] ' + this.username + ';' + this.password)
}
}
function setupBAS() {
window.BasSettings = new BasSettingsClass()
window.BasSettings.logCredentials()
// eslint-disable-next-line no-undef
window.BasApi = Api
}
function loadMainInterface() {
console.log('loadMainInterface')
// Create the script element
var script = document.createElement('script')
script.type = 'module'
script.crossOrigin = 'anonymous'
script.src = window.BasSettings.baseUrl + '/assets/index.js'
// Create the link element
var link = document.createElement('link')
link.rel = 'stylesheet'
link.href = window.BasSettings.baseUrl + '/assets/index.css'
// Append the script and link elements to the head
document.head.appendChild(script)
document.head.appendChild(link)
}
document.addEventListener('DOMContentLoaded', function() {
setupBAS()
/////Api event handler
// eslint-disable-next-line no-unused-vars,no-undef
Api.SetEventHandler(function(EventType, EventData) {
/////Script started
if (EventType === 'start') {
console.log('Script started')
}
/////Script stopped
if (EventType === 'stop') {
console.log('Script stopped')
}
/////More events: https://wiki.bablosoft.com/web-interface/#/managingscriptlifetime
})
loadMainInterface()
/////Automatically start script https://wiki.bablosoft.com/web-interface/#/managingscriptlifetime?id=method-acceptresources
// eslint-disable-next-line no-undef
Api.AcceptResources(true)
/////Events
})
/////Resource values are obtained through this function when hitting run button, you can change it.
/////For example, you can edit value entered by user, make custom validation, or replace resource system completely
/////More info: https://wiki.bablosoft.com/web-interface/#/managingscriptlifetime?id=method-acceptresources
// eslint-disable-next-line no-unused-vars
function GetResourceValue(ResourceName) {
if (ResourceName === 'USERNAME') {
return window.BasSettings.username
}
if (ResourceName === 'PASSWORD') {
return window.BasSettings.password
}
//Unknown resource name
return ''
}
//Interface editor has no connection to BAS and therefore can't execute BAS functions.
//If you try to call function from interface editor,
//you will get a random string as result in a several seconds.
//This behavior is not acceptable in several cases: if your function return a list,
//not a string, or string in specific format, if you want to test error handling, etc.
//In order to circumvent this limitation. you need to define "EmulateFunctionRun"
//function inside web interface.
//More info: https://wiki.bablosoft.com/web-interface/#/callbasfunction?id=debugging-bas-function-call
// eslint-disable-next-line no-unused-vars
function EmulateFunctionRun(FunctionName, FunctionParameters, Resolve, Reject) {
//Generate random data
var RandomTime = Math.floor(Math.random() * (5000 - 3000)) + 3000
var RandomResult = Math.floor(Math.random() * (1000))
//Return result in RandomTime milliseconds
setTimeout(function() {
//Generate result string
Resolve('Test result ' + RandomResult)
}, RandomTime)
}
<!-- VueJs -->
<div id="app"></div>

P.S.
Как интегрировать Vue.js и BAS API и как это тестировать - это отдельная большая история.