Reputation: 105
I have a vue project that use CDN to getting it libs for running. Now I want to add a integrity property on the script label to verify the script it pull from CDN. And I want the code automatic generate the hash of script and insert is to the dist when i build the project.
I want a some sync function like this:
function integrityWapper ({ css, js }) {
const hash = require('crypto-js').SHA384
const icss = []; const ijs = []
for (const i in css) {
icss.push([css[i], hash(GettingScriptContentFromWeb(css[i]))])
}
for (const i in js) {
ijs.push([js[i], hash(GettingScriptContentFromWeb(js[i]))])
}
return { icss, ijs }
}
Obviously, this function cannot be async cause i am trying to generate config for vue.config.js
, so the GettingScriptContentFromWeb
function must also be sync.
Is there a way turn call async function(i mean axios.get) in sync function and wait it to finish?
Update:
No, i can't just rewrite the upstream cause i need export the result in vue.config.js
, this is some code i currently use:
** vue.config.js **
module.exports = defineConfig({
integrity: true,
pages: {
index: {
entry: 'src/main.ts',
template: 'public/index.html',
filename: 'index.html',
CDN: cdnConfig.use ? cdnConfig.list : null
}
}
})
//cdnConfig.list is like this:
list: {
css: [
[
'https://cdn.bootcdn.net/ajax/libs/element-plus/2.2.13/index.css',
'sha384-WdBufJjVUMBy2e6mTgtUbbYZvZg7vdYW3ijXdfg4jglZAehE17bPFaxNMhFXuH1Z'
]
],
js: [
[
'https://cdn.bootcdn.net/ajax/libs/vue/3.2.37/vue.global.prod.min.js',
'sha384-MB7auY3xTNj+3Hk53DrKFyXN7Djh50mLDesxCDPr4XENv8gK06a3RqhmkXBfcPFh'
]
]
}
Or can somebody tell me how can i rewrite the part that vue and webpack read these config?
Should i just write this script in a other file and i run it before vue-cli-service build
in npm run build
, or i try to use package like deasync or sync-kit?
Upvotes: 2
Views: 6220
Reputation: 370
As you are dealing with http api's the result is always going to be asynchronous. From the context, i am assuming you want to execute this script when you are building the project, something like yarn dostuff
.
This can be achieved like by wrapping the async function in a self executing function
index.js
async function integrityWapper ({ css, js }) {
const hash = require('crypto-js').SHA384
const icss = []; const ijs = []
for (const i in css) {
icss.push([css[i], hash(await GettingScriptContentFromWeb(css[i]))])
}
for (const i in js) {
ijs.push([js[i], hash(await GettingScriptContentFromWeb(js[i]))])
}
return { icss, ijs }
}
const executor = (async ()=>{
await integrityWapper({
css: process.env.CSS,
js: process.env.JS
});
})();
export default executor;
And then add a script in package.json
"scripts": {
"dostuff": "node index.js",
"custom-build": "yarn dostuff && yarn build"
},
Something on the lines of above
Hope i made sense
Upvotes: 0
Reputation: 707916
Is there a way turn call async function(i mean axios.get) in sync function and wait it to finish?
No, there is not. axios.get()
is asynchronous and you cannot get its result synchronously.
You will have to rewrite your code to use an asynchronous design. Probably, GettingScriptContentFromWeb()
needs to return a promise and integrityWrapper()
needs to use that promise and also needs to return a promise. The caller of integrityWrapper()
then needs to use .then()
or await
on the promise that integrityWrapper()
will return to get the resolved value.
For example, if you changed GettingScriptContentFromWeb()
to return a promise that resolves to it's value, then you could do this:
async function integrityWapper ({ css, js }) {
const hash = require('crypto-js').SHA384
const icss = []; const ijs = []
for (const i in css) {
icss.push([css[i], hash(await GettingScriptContentFromWeb(css[i]))])
}
for (const i in js) {
ijs.push([js[i], hash(await GettingScriptContentFromWeb(js[i]))])
}
return { icss, ijs }
}
integrityWrapper(...).then(result => {
// use the asynchronously retrieved result here
}).catch(err => {
// got some error here
});
P.S. if css
or js
are arrays, then you should be using for/of
to iterate arrays, not for/in
. If they are objects, then you can use for/in
to iterate their enumerable properties.
Upvotes: 1