Why debug on Webpack v5 Vue is no longer working? - vue.js

I recently updated #vue's webpack and submodules to v5 following this. This was necessary because web workers were not working with v4. Now my problem is that I'm not able to debug the code and I don't know where to start. I accept any suggestion that helps me diagnose the problem
The code runs normally, it just doesn't stop on breakpoints anymore. My vue.config.js has a configuration in the devtoolModuleFilenameTemplate that if I'm not mistaken it was supposed to work with .ts files, I've tried to remove it and it didn't help.
I searched around here and couldn't find anyone with a similar problem. My current version is at 5.0.8 but I also tried 5.0.1.
vue.config.js:
/* eslint-disable */
const CompilerSfc = require('#vue/compiler-sfc')
const parse = CompilerSfc.parse
CompilerSfc.parse = (source, options) => {
return parse(source, Object.assign({ pad: true }, options))
}
module.exports = {
devServer: {
allowedHosts: 'all',
port: 5000,
host: '0.0.0.0',
},
configureWebpack: {
devtool: 'source-map',
output: {
devtoolModuleFilenameTemplate: (info) => {
if (info.allLoaders === '') {
// when allLoaders is an empty string the file is the original source
// file and will be prefixed with src:// to provide separation from
// modules transpiled via webpack
const filenameParts = ['src://']
if (info.namespace) {
filenameParts.push(info.namespace + '/')
}
filenameParts.push(info.resourcePath.replace(/^\.\//, ''))
return filenameParts.join('')
} else {
// otherwise we have a webpack module
const filenameParts = ['webpack://']
if (info.namespace) {
filenameParts.push(info.namespace + '/')
}
filenameParts.push(info.resourcePath.replace(/^\.\//, ''))
const isVueScript =
info.resourcePath.match(/\.vue$/) &&
info.query.match(/\btype=script\b/) &&
!info.allLoaders.match(/\bts-loader\b/)
if (!isVueScript) {
filenameParts.push('?' + info.hash)
}
return filenameParts.join('')
}
},
},
},
}
launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "vue.js: chrome",
"request": "launch",
"type": "chrome",
"url": "http://localhost:5000",
"webRoot": "${workspaceFolder}/src"
}
]
}

You can put debugger key directly in your code, instand of breakpoint in vscode. Then, debug with your browser.
Here is an example :
Hope it hopes :)

Related

how to convert Nuxt js (pwa) project to apk?

I am working on a nuxt project and I want to add it to Google Play, but it requires an apk output
so is there any solution to get the apk file from Nuxt?
I've already tried using android studio but it was unsuccessful
manifest.json:
{
"name": "my nuxt app",
"short_name": "my lovely nuxt app",
"description": "pwa to apk",
"icons": [
{
"src": "/logo.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/300.png",
"sizes": "384x384",
"type": "image/jpg"
},{
"src": "/512.jpg",
"sizes": "512x512",
"type": "image/jpg"
}
],
"start_url": "/?standalone=true",
"display": "standalone",
"background_color": "#222",
"theme_color": "#222",
"lang": "fa",
"prefer_related_applications": true
}
and I get this error when I want to install it:
for security your phone is set to block installation
TWA are a thing as you can read here: https://www.ateamsoftsolutions.com/what-are-pwa-and-twa/
Meanwhile, this is not the same as having an .apk which is something totally different from the Web platform as you can see here: https://fileinfo.com/extension/apk (none of the extensions are ones used on the Web)
This is a totally different bundle language and ecosystem. Hence, you cannot port a PWA into a Google Play app.
You'll need to learn ways to make a mobile app with either Capacitor (Quasar) can help or similar solutions.
Or use React Native, Flutter or even vanilla Kotlin (the latter being the closest one to the machine).
In addition to kissu's comment, I always use Nuxt.js for regular websites but Ionic/Vue with Capacitor for mobile apps, it works great, same ecosystem and a great UI components and CLI from Ionic. This is just a suggestion for something that works and it has a minimum learning curve.
after so many searches and thanks to #kissu for give me a hint about twa i found the solution:
1.first of all u need a service worker for your nuxt project and put it in the static folder
example:
/static/sw.js
and inside of sw.js:
const options = {"workboxURL":"https://cdn.jsdelivr.net/npm/workbox-cdn#5.1.4/workbox/workbox-sw.js","importScripts":[],"config":{"debug":false},"cacheOptions":{"cacheId":"online-actor-prod","directoryIndex":"/","revision":"c35hcbL1ctml"},"clientsClaim":true,"skipWaiting":true,"cleanupOutdatedCaches":true,"offlineAnalytics":false,"preCaching":[{"revision":"c35hcbL1ctml","url":"/"}],"runtimeCaching":[{"urlPattern":"/_nuxt/","handler":"CacheFirst","method":"GET","strategyPlugins":[]},{"urlPattern":"/","handler":"NetworkFirst","method":"GET","strategyPlugins":[]}],"offlinePage":null,"pagesURLPattern":"/","offlineStrategy":"NetworkFirst"}
importScripts(...[options.workboxURL, ...options.importScripts])
initWorkbox(workbox, options)
workboxExtensions(workbox, options)
precacheAssets(workbox, options)
cachingExtensions(workbox, options)
runtimeCaching(workbox, options)
offlinePage(workbox, options)
routingExtensions(workbox, options)
function getProp(obj, prop) {
return prop.split('.').reduce((p, c) => p[c], obj)
}
function initWorkbox(workbox, options) {
if (options.config) {
// Set workbox config
workbox.setConfig(options.config)
}
if (options.cacheNames) {
// Set workbox cache names
workbox.core.setCacheNameDetails(options.cacheNames)
}
if (options.clientsClaim) {
// Start controlling any existing clients as soon as it activates
workbox.core.clientsClaim()
}
if (options.skipWaiting) {
workbox.core.skipWaiting()
}
if (options.cleanupOutdatedCaches) {
workbox.precaching.cleanupOutdatedCaches()
}
if (options.offlineAnalytics) {
// Enable offline Google Analytics tracking
workbox.googleAnalytics.initialize()
}
}
function precacheAssets(workbox, options) {
if (options.preCaching.length) {
workbox.precaching.precacheAndRoute(options.preCaching, options.cacheOptions)
}
}
function runtimeCaching(workbox, options) {
const requestInterceptor = {
requestWillFetch({ request }) {
if (request.cache === 'only-if-cached' && request.mode === 'no-cors') {
return new Request(request.url, { ...request, cache: 'default', mode: 'no-cors' })
}
return request
},
fetchDidFail(ctx) {
ctx.error.message =
'[workbox] Network request for ' + ctx.request.url + ' threw an error: ' + ctx.error.message
console.error(ctx.error, 'Details:', ctx)
},
handlerDidError(ctx) {
ctx.error.message =
`[workbox] Network handler threw an error: ` + ctx.error.message
console.error(ctx.error, 'Details:', ctx)
return null
}
}
for (const entry of options.runtimeCaching) {
const urlPattern = new RegExp(entry.urlPattern)
const method = entry.method || 'GET'
const plugins = (entry.strategyPlugins || [])
.map(p => new (getProp(workbox, p.use))(...p.config))
plugins.unshift(requestInterceptor)
const strategyOptions = { ...entry.strategyOptions, plugins }
const strategy = new workbox.strategies[entry.handler](strategyOptions)
workbox.routing.registerRoute(urlPattern, strategy, method)
}
}
function offlinePage(workbox, options) {
if (options.offlinePage) {
// Register router handler for offlinePage
workbox.routing.registerRoute(new RegExp(options.pagesURLPattern), ({ request, event }) => {
const strategy = new workbox.strategies[options.offlineStrategy]
return strategy
.handle({ request, event })
.catch(() => caches.match(options.offlinePage))
})
}
}
function workboxExtensions(workbox, options) {
}
function cachingExtensions(workbox, options) {
}
function routingExtensions(workbox, options) {
}
2.you also need a manifest , for that put this code in your nuxt.config.js:
export default{
pwa: {
manifest: {
name: 'example name',
short_name: 'example',
lang: 'fa',
theme_color: '#222',
background_color: '#222',
start_url: `/`,
prefer_related_applications: true,
},
icon: {
fileName: 'logo.png'
},
},
}
3.now everything is ready to create your apk, now you can search for pwa to apk in google And use sites that offer these services:
ive already tried these sites and all working well:
gonative.io
or
pwabuilder.com

Avoid browser caching after deploy a Vuejs app

My Vuejs App did not update after deployment for production, every time require "Empty cache and hard reload" to get the updates, I tried a lot of solutions to apply versioning to generated files after build but none of them worked for me, I need a solution to apply new hash for all files after every single build, not just the updated ones.
My vue.config.js file content:
const path = require("path");
module.exports = {
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
runtimeCompiler: true,
configureWebpack: {
resolve: {
alias: {
// If using the runtime only build
// vue$: "vue/dist/vue.runtime.esm.js" // 'vue/dist/vue.runtime.common.js' for webpack 1
// Or if using full build of Vue (runtime + compiler)
vue$: 'vue/dist/vue.esm.js', // 'vue/dist/vue.common.js' for webpack 1
'#': path.resolve('src'),
src: path.resolve('src'),
assets: path.resolve('src/assets'),
components: path.resolve('src/components'),
services: path.resolve('src/services'),
}
},
output: {
filename: '[name].[hash].js',
},
},
chainWebpack: config => {
config.module
.rule("eslint")
.use("eslint-loader")
.tap(options => {
options.configFile = path.resolve(__dirname, ".eslintrc.js");
return options;
});
},
};
Thanks in advance.
Welcome to the Vue JS cache nightmare. Did you try changing the version value in your package.json? I use to increment the value on each release as per x.y.z semantinc versioning. Maybe doing something like this:
{
"name": "My app",
"version": "1.0.15",
"private": true,
...
}

Serving a modified asset-manifest.json in CRA using CRACO doesn't work

I have just created a new CRA app. In our organization we have a micro frontend framework which has certain requirements when it comes to the the asset file of each micro frontend app. CRA will by default, create a asset-manifest.json file.
https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L656
Now I need to change this file to assets.json and make some structural changes as well. To achieve this I use CRACO and add the WebpackManifestPlugin.
const ManifestPlugin = require('webpack-manifest-plugin');
module.exports = {
webpack: {
plugins: {
// tried removing CRA definition for ManifestPlugin.
// It worked, but had no impact on my problem
// remove: ['ManifestPlugin'],
add: [
new ManifestPlugin({
fileName: 'assets.json',
generate: (seed, files, entrypoints) => {
const js = [],
css = [];
files.forEach((file) => {
if (file.path.endsWith('.js') && file.isInitial) {
js.push({ value: file.path, type: 'entry' });
}
if (file.path.endsWith('.css') && file.isInitial) {
css.push({ value: file.path, type: 'entry' });
}
});
return { js, css };
},
})
]
}
}
};
Whenever I build the application, my new assets.json file is generated as expected.
However, I can't get CRA, or webpack-dev-server I assume, to serve this file while I run my CRA app in development mode. It only resolves to the index.html file. I have looked through CRA source code and can't really find any relevant place where asset-manifest.json is mentioned.
So how do I get webpack-dev-server to serve my assets.json file?
You need to add the ManifestPlugin to webpack.plugins.remove array to receive only the configuration from WebpackManifestPlugin:
...
webpack: {
alias: {},
plugins: {
add: [
new WebpackManifestPlugin(webpackManifestConfig)
],
remove: [
"ManifestPlugin"
],
},
configure: (webpackConfig, { env, paths }) => { return webpackConfig; }
},
...

Storybook with craco - call a different verson of react-scripts

Storybook currently calls react-scripts. However, I've got some parts of the CRA config overriden with craco. It means my application is invoked with craco ..., rather than react-scripts ....
Is there a clean solution to have Storybook call craco instead?
The solution I came up with is this :
.storybook/main.js :
const path = require('path');
module.exports = {
stories: ['../src/**/*.stories.js'],
addons: [
'#storybook/preset-create-react-app',
'#storybook/addon-actions',
'#storybook/addon-links',
'#storybook/addon-viewport/register',
'#storybook/addon-knobs/register',
],
webpackFinal(config, { configType }) {
return {
...config,
resolve: {
alias: {
...config.resolve.alias,
'~': path.resolve(__dirname, '../src/'),
},
},
};
},
};
I was only using the alias feature in my craco file, so here I override webpack config from storybook and only add the alias parameter. For your case, you'll need to add your own config.
The #FR073N solution is good, but since the lasts versions, this throw an error.
One line was missing to fully override correctly the webpack config.
const path = require('path');
module.exports = {
stories: ['../src/**/*.stories.js'],
addons: [
'#storybook/preset-create-react-app',
'#storybook/addon-actions',
'#storybook/addon-links',
'#storybook/addon-viewport/register',
'#storybook/addon-knobs/register',
],
webpackFinal(config, { configType }) {
return {
...config,
resolve: {
...config.resolve, // <= HERE
alias: {
...config.resolve.alias,
'~': path.resolve(__dirname, '../src/'),
},
},
};
},
};
I've successfully used storybook-preset-craco with #storybook#6.3.5 and react-scripts#4.0.3 and #craco/craco#6.2.0 in a new CRA TypeScript project.

Babel aliases. WebStorm doesn't recognize sub-directories

I recently moved from webpack path aliases to babel-plugin-module-resolved as it integrates better with testing frameworks.
.babelrc
{
"presets": [
["env", { "modules": false } ],
"react",
"stage-2",
"flow"
],
"plugins": [
["module-resolver", {
"alias": {
"static": "./static",
"common": "./src/common",
"data": "./src/data"
}
}],
["styled-jsx/babel", { "plugins": ["styled-jsx-plugin-sass"] }],
"react-hot-loader/babel"
]
}
WebStorm automatically recognizes imports for static/.. but can't resolve imports like common/.. and data/...
Is it possible to somehow instruct IDE about this configuration?
P.S. Right now I have src directory marked as Resource Root but this doesn't quite work as well.
One option I've taken is to create a fake webpack file that creates the same aliases. Leaves an unnecessary file in your codebase, but fixes all the name resolution issues.
Example:
webpack.junk.js
module.exports = {
resolve: {
alias: {
'static': path.resolve(__dirname, './static'),
'#common': path.resolve(__dirname, './src/common'),
'#data': path.resolve(__dirname, './src/data'),
},
},
};
Following SimplyComplexable's solution (I can't comment on his reply, sorry), I've create a new webpack.intellij.js that loads the project's webpack config (webpack.js), reads the .babelrc file to generates the resolve.alias section for the exported config, then explicitly pointed IntelliJ to this file in the preferences:
const path = require('path');
const fs = require('fs');
const { merge } = require('webpack-merge');
const webpackConfig = require('./webpack.js');
const babelRc = JSON.parse(fs.readFileSync('./.babelrc').toString('utf8'));
const aliases = {};
for (let i = 0; i < babelRc.plugins.length; i+=1) {
if (Array.isArray(babelRc.plugins[i]) &&
babelRc.plugins[i][0] === 'module-resolver') {
const a = babelRc.plugins[i][1].alias;
for (const entry of Object.entries(a)) {
aliases[entry[0]] = path.resolve(__dirname, entry[1]);
}
}
}
module.exports = merge(webpackConfig, {
resolve: {
alias: aliases
}
});
This solution allows me to have the aliases configured in one single place (.babelrc) while still having IntelliJ recognise them :)