Vite.js Dynamic Image Loading Fails In Production - vue.js

I have a problem in importing dynamic assets in production mode. When I ran the development environment everything works fine and the assets loads...but when I build the Vue.js application, assets won't load and I gets below error:
TypeError: URL constructor: ../../../assets/images/name.png is not a valid URL.
how can I fix this issue?
Vue Example
<img :src="findImageFromNumber(card.cartNumber)" alt="image" width="25" />
function findImageFromNumber(number: string) {
const name = identify(number).english;
const path = new URL('../../../assets/images/banks/' + name + '.png', import.meta.url);
return path.href
}
Vite.js Config
export default defineConfig({
root: './',
resolve: {
alias: {
'/#/': path.resolve(__dirname, 'src')
},
},
publicDir: 'assets',
mode: 'production',
build: {
outDir: 'dist',
sourcemap: true,
target: ['es2019', 'safari11', 'firefox60', 'chrome61', 'node12'],
chunkSizeWarningLimit: 500,
minify: false,
emptyOutDir: true,
assetsInlineLimit: 2048,
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`,
manualChunks(id) {
if (id.includes('vue')) {
return 'react';
} else if (id.includes('node_modules')) {
return 'vendor';
}
},
},
}
},
plugins: [
vue(),
legacy({
polyfills: ['es.promise.finally', 'es/map', 'es/set'],
modernPolyfills: ['es.promise.finally']
})
],
})
Note: Everything works fine in development and it only fails in production...

Assets is your public dir. Should it just be /assets/images/banks, according to the docs?

Related

webpack.config + nuxt.config,js

I am new to nuxt.
I want to add following webpack config (from docs for ckeditor vue) to nuxt.js.config
https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/frameworks/vuejs-v2.html
const path = require( 'path' );
const CKEditorWebpackPlugin = require( '#ckeditor/ckeditor5-dev-webpack-plugin' );
const { styles } = require( '#ckeditor/ckeditor5-dev-utils' );
module.exports = {
// The source of CKEditor is encapsulated in ES6 modules. By default, the code
// from the node_modules directory is not transpiled, so you must explicitly tell
// the CLI tools to transpile JavaScript files in all ckeditor5-* modules.
transpileDependencies: [
/ckeditor5-[^/\\]+[/\\]src[/\\].+\.js$/,
],
configureWebpack: {
plugins: [
// CKEditor needs its own plugin to be built using webpack.
new CKEditorWebpackPlugin( {
// See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html
language: 'en',
// Append translations to the file matching the `app` name.
translationsOutputFile: /app/
} )
]
},
// Vue CLI would normally use its own loader to load .svg and .css files, however:
// 1. The icons used by CKEditor must be loaded using raw-loader,
// 2. The CSS used by CKEditor must be transpiled using PostCSS to load properly.
chainWebpack: config => {
// (1.) To handle editor icons, get the default rule for *.svg files first:
const svgRule = config.module.rule( 'svg' );
// Then you can either:
//
// * clear all loaders for existing 'svg' rule:
//
// svgRule.uses.clear();
//
// * or exclude ckeditor directory from node_modules:
svgRule.exclude.add( path.join( __dirname, 'node_modules', '#ckeditor' ) );
// Add an entry for *.svg files belonging to CKEditor. You can either:
//
// * modify the existing 'svg' rule:
//
// svgRule.use( 'raw-loader' ).loader( 'raw-loader' );
//
// * or add a new one:
config.module
.rule( 'cke-svg' )
.test( /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/ )
.use( 'raw-loader' )
.loader( 'raw-loader' );
// (2.) Transpile the .css files imported by the editor using PostCSS.
// Make sure only the CSS belonging to ckeditor5-* packages is processed this way.
config.module
.rule( 'cke-css' )
.test( /ckeditor5-[^/\\]+[/\\].+\.css$/ )
.use( 'postcss-loader' )
.loader( 'postcss-loader' )
.tap( () => {
return {
postcssOptions: styles.getPostCssConfig( {
themeImporter: {
themePath: require.resolve( '#ckeditor/ckeditor5-theme-lark' )
},
minify: true
} )
};
} );
}
};
My nuxt config is simply current, i did add some modules like axios,boostrap vue and auth to it.
export default {
// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
ssr: false,
// Target: https://go.nuxtjs.dev/config-target
target: "static",
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: "spa",
htmlAttrs: {
lang: "en",
},
meta: [
{ charset: "utf-8" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },
{ hid: "description", name: "description", content: "" },
{ name: "format-detection", content: "telephone=no" },
],
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: ["~/assets/less/colors.less"],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/bootstrap
"bootstrap-vue/nuxt",
"#nuxtjs/axios",
"#nuxtjs/auth-next",
],
auth: {
redirect: {
login: "/login",
logout: "/login",
callback: false,
home: "/",
},
strategies: {
laravelSanctum: {
provider: "laravel/sanctum",
url: "http://localhost",
user: {
property: false, // <--- Default "user"
autoFetch: true,
},
// endpoints: {
// login: { url: "api/login", method: "post" },
// logout: { url: "api/auth/logout", method: "post" },
// user: { url: "api/user", method: "get" },
// },
},
},
},
axios: {
credentials: true,
baseURL: "http://localhost", // Used as fallback if no runtime config is provided
// withCredentials: true,
headers: {
accept: "application/json",
common: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,PATCH,OPTIONS",
"Access-Control-Allow-Credentials": true,
},
delete: {},
get: {},
head: {},
post: {},
put: {},
patch: {},
},
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
router: {
middleware: ["auth"],
},
};
And if config like that can be combine with webpack config for ckeditor , is that right way to do so ?
Or should i separate this and build in another direcrory with another sepparate webpack config?
I guess you're looking for that one: https://nuxtjs.org/docs/configuration-glossary/configuration-build#extend
Could create an external config and import it into this object or directly do that inline as most people do.
There are quite some answers on Stackoverflow anyway on how to achieve specific parts of the configuration, feel free to give it a search to find out what you need.

vue plugin pwa sw.js not found

I have 1 app using the vue pwa plugin, it works great.
The vuejs config for the app looks like this:
const WebpackNotifierPlugin = require('webpack-notifier')
module.exports = {
lintOnSave: false,
css: {
loaderOptions: {
sass: {
implementation: require('sass')
}
}
},
transpileDependencies: [
'vuex-module-decorators',
'vuex-persist'
],
pwa: {
name: 'MyApp',
themeColor: '#000000',
msTileColor: '#000000',
appleMobileWebAppCapable: 'yes',
appleMobileWebAppStatusBarStyle: 'black',
// configure the workbox plugin
workboxPluginMode: 'InjectManifest',
workboxOptions: {
// swSrc is required in InjectManifest mode.
swSrc: 'dev/sw.js',
// ...other Workbox options...
}
},
configureWebpack: {
devServer:{
historyApiFallback: true,
},
plugins: [
new WebpackNotifierPlugin(),
],
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: 3,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
return `npm.${packageName.replace('#', '')}`;
},
},
},
},
},
},
}
I have another app, exactly the same, vue2, beufy etc etc.. i installed the same stuff via the vue pwa plugin and the config looks exactly the same but when i run build it says it cannot find the sw.js file:
Error: ENOENT: no such file or directory, open 'dev/sw.js'
I have created a uber basic vue app which does the same thing here: https://github.com/johndcarmichael/vue-pwa-sw-not-found
Has anyone else got this issue, and how did you resolve it?
You are not having dev/sw.js in your project, as you set in swSrc. InjectManifest means take this sw.js source file and write precache manifest into it, producing the final service-worker.js file.

Exporting Vue components as npm module

I have problem to make Vue component export work properly.
I can export the component successfully and when I try to import it in different project I get this error:
[Vue warn]: Failed to mount component: template or render function not defined.
This is the Webpack config that I use for export:
const webpack = require('webpack');
const path = require('path');
const utils = require('./utils');
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
var config = {
entry: path.resolve(__dirname + '/../src/components/index.js'),
output: {
path: path.resolve(__dirname + '/../dist/timer-comp/'),
filename: 'timer-component.js',
},
resolve: {
extensions: ['.vue', '.js', '.json']
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
}
]
},
plugins: [
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
sourceMap: false,
mangle: true,
compress: {
warnings: false
}
})
]
};
module.exports = config;
This is the code that I use to export the components:
import TimerComponent from './timer-component';
export {
TimerComponent,
};
And finally the component code:
<template>
<div>
<div class="time">{{time}}</div>
</div>
</template>
<script>
export default {
name: 'TimerComponent',
data() {
return {
time: ''
};
},
created() {
setInterval(() => {
let now = new Date();
this.time = now.getHours() + " : " + now.getMinutes() + " : " + now.getSeconds();
}, 1000);
}
}
</script>
<style scoped>
</style>
Does someone have a clue why I get this error Failed to mount component ?
by the way this is how I call the component in a different project:
import TimerComponent from 'timer-comp';
It seems that the issue is caused by the build somehow, but I can't figure out what could be the exact problem.
add output property in production webpack config file:
output: {
path: path.resolve(__dirname + '/../dist/timer-comp/'),
filename: 'timer-component.js',
libraryTarget: 'umd',
libraryExport: 'default',
library: 'TimerComponent',
umdNamedDefine: true
}

I could not import exported variables from an es2015 NPM module

I have an npm module named sidebar. I use webpack to compile the es2015 src files into a single file. So far running webpack does not output any problem and creates a file, lib/sidebar.min.js
I have set the it to be the main file in package.json
...
"description": "",
"main": "lib/sidebar.min.js",
"scripts": {
...
I have this in my src/index.js file
export const foo = 'foo'
export const bar = 'bar'
I tried using this module in my main project
import { foo, bar } from 'sidebar'
console.log(foo)
console.log(bar)
Both console log calls outputs undefined
After searching the internet for hours, I am totally stumped as to why this is a problem.
Any ideas?
EDIT: Here is the webpack config for the main repository
var webpackConfig = {
entry: {
app: './src/app/main.app.js',
vendor: ['angular']
},
output: {
path: DIST_DIRECTORY + '/scripts/',
publicPath: '/scripts/',
filename: '[name].min.js',
chunkFilename: '[name].min.js'
},
devtool: 'source-map',
module: {
loaders: [{
test: /\.js$/,
loader: 'babel'
}, {
test: /\.html$/,
loader: 'raw'
}]
},
plugins: [
new webpack.NoErrorsPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
unused: true,
dead_code: true
},
sourceMap: true
}),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.bundle.js")
],
devServer: {
contentBase: DIST_DIRECTORY + '/'
}
};

Syntax error when testing React component Jasmine and Webpack

I keep getting an error when trying to run a simple test using React, Karma, Jasmine and Webpack. The error is ' Uncaught SyntaxError: Unexpected token < ', I think my jsx isn't being processed to js, but I don't know why that is happening as I understand webpack should handle that using the babel loader. If anyone can provide advice I would be grateful
Here are my files
karma.conf.js
var webpack = require("webpack"),
path = require("path");
// Karma configuration
module.exports = function(config) {
config.set({
basePath: "",
frameworks: ["jasmine"],
files: [
"../test/!**!/!*.test.js"
],
preprocessors: {
"./test/!**!/!*.test.js": ["webpack"]
},
webpack: {
module: {
loaders: [
{
test: /\.jsx?$/i,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},
{ test: /\.less$/, loader: "style!css!less" }
]
},
},
plugins: [
new webpack.ResolverPlugin([
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
])
],
resolve: {
root: __dirname,
extensions: [
'',
'.json',
'.js',
'.jsx'
]
}
},
webpackMiddleware: {
noInfo: true
},
plugins: [
require("karma-webpack"),
require("karma-jasmine"),
require("karma-chrome-launcher")
],
reporters: ["dots"],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ["Chrome"],
singleRun: false
});
};
my test file example.test.js
var Comp = require('../../../js/common/components/MyComp.jsx'),
React = require('react'),
TestUtils = React.addons.TestUtils;
describe("Component Test", function() {
it("renders an h1", function () {
var component = TestUtils.renderIntoDocument(
<Comp/> // syntax error here
);
var h2 = TestUtils.findRenderedDOMComponentWithTag(
component, 'h2'
);
expect(h1).toExist();
});
});
So the syntax error happens at < Comp... . Thanks!
Apologise it was an error in setting the correct path to the test file.
files: [
"../test/**/*.test.js"
],
preprocessors: {
"../test/**/*.test.js": ["webpack"]
},