Load external library from CDN under an alias - javascript

I need to load two versions of the same library from CDN. Is there a way to specify the name of the resulting object on window so that they don't clash? Or can I rename the first before the second loads?

<script src="lib#1" />
<script> window.lib1 = window.lib; </script>
<script src="lib#2" />
then
window.lib1 // is lib#1
window.lib // is lib#2

Based on Jonas Wilms' answer, I came up with these two solutions when using webpack, which I have not mentioned in the original question.
here is a Demo https://codesandbox.io/s/multiple-library-versions-kvg5d
webpack - externals
you must change webpack config when updating a package
module.exports = {
externals: {
react: 'React16_11'
}
};
in code
import React from 'react' // webpack translates to window.React16_11
webpack - aliases*
you must change a .js file in project when updating a package
module.exports = {
alias: {
react$: './getReactFromWindow',
},
};
getReactFromWindow.js:
module.exports = window.React16_11;
in code
import React from 'react' // webpack translates to './getReactFromWindow'
*webpack aliases based on this question

Related

How can I make a file available app wide without importing it?

I have a file that I want available app wide, if the file is called app_wide.js normally I would do
import util from './app_wide.js'
However, I it is a small file and I want its exports available in all my files without the explicit import command. How can I go about doing this?
I'm using Webpack to build a React application.
Maybe you can use webpack provide-plugin
https://webpack.js.org/plugins/provide-plugin/
for example:
hello.js
const hello = () => {
console.log('hello');
};
module.exports = hello;
webpack.config.js
plugins: [
new webpack.ProvidePlugin({
$hello: path.resolve(path.join(__dirname, './hello.js'))
// ...
})
]
App.js
// don't need imported or required hello from 'hello.js'
$hello()
when you use typescript don't forget to declare the type
hello.d.ts
declare function $hello(): void;

Overwrite an existing plugin JS in Shopware 6

I am currently trying to overwrite a javascript file from an existing plugin.
I've been following the documentation but I am struggling with the path for the JS class to overwrite.
In the docs is an example code:
import CookiePermissionPlugin from 'src/plugin/cookie/cookie-permission.plugin';
export default class MyCookiePermission extends CookiePermissionPlugin {
}
So I implemented the following code:
import QuantityField from 'src/plugin/FilterRangeSlider/filter-range-slider.plugin';
export default class ExampleQuantityField extends QuantityField {
This code does not work for me, since the original file is in the vendor directory and my plugin is in the custom directory. When trying to compile (eg bin/build-storefront.sh) I receive the following error message:
Module not found: Error: Can't resolve 'src/plugin/FilterRangeSlider/filter-range-slider.plugin' in '<project root>/custom/plugins/ExampleProductFilter/src/Resources/app/storefront/src/filter-range-slider'
Any idea how I can import that class as stated in the docs?
Node.js provides a bunch of in-built file-system functionalities. The __dirname points to the root directory.
So, this should work.
import QuantityField from `${__dirname}/vendor/store.shopware.com/mmeesrangesliderpro/src/Resources/app/storefront/src/script/filter-range-slider.plugin`
My current solution is not really clean...
import QuantityField from '../../../../../../../../../vendor/store.shopware.com/mmeesrangesliderpro/src/Resources/app/storefront/src/script/filter-range-slider.plugin';
Isnt there any plugin root variable or something similar?
There is - I believe - no easier way to accomplish this.
If each plugin would extend the webpack config as described in
https://developer.shopware.com/docs/guides/plugins/plugins/administration/extending-webpack
const path = require('path');
module.exports = () => {
return {
resolve: {
alias: {
MmeesRangeSliderPro: path.join(__dirname, '..', 'src')
}
}
};
};
The alias could be used instead of the Plugin Root.
But this is not the case, so the following is not working:
import QuantityField from 'MmeesRangeSliderPro/plugin/FilterRangeSlider/filter-range-slider.plugin';
You can add a console.log(webpackConfig) to the bottom of Resources/app/storefront/webpack.config.js to validate this.
alias: {
src: '/home/user/example/projects/example.de/vendor/shopware/storefront/Resources/app/storefront/src',
assets: '/home/user/example/projects/example.de/vendor/shopware/storefront/Resources/app/storefront/assets',
jquery: 'jquery/dist/jquery.slim',
scss: '/home/user/example/projects/example.de/vendor/shopware/storefront/Resources/app/storefront/src/scss',
vendor: '/home/user/example/projects/example.de/vendor/shopware/storefront/Resources/app/storefront/vendor'
}
And those again to not really allow locating the module.
If it is a third-party plugin, replace the path with an absolute path like the following
import ThirdPartyPlugin from '/app/custom/plugins/ThirdPartyPlugin/src/Resources/app/storefront/src/third-party-plugin/third-party-plugin.plugin';

Cannot use newly installed plugins (node modules) in Nuxt pages/components

First off, I'm a beginner with NuxtJS and front-end development in general, so it might be that I'm missing something - though I do believe I went through all the options before posting here. Apologies in advance if that is not the case.
I've been having trouble using installed modules that I've registered as plugins. For example, take mapbox-sdk.
After installing it with npm install #mapbox/mapbox-sdk, which correctly creates #mapbox/mapbox-sdk in node_modules, I register it in nuxt.config.js:
plugins: [
...
"~/plugins/mapbox-sdk.js",
],
Of course, I also create the mapbox-sdk.js file in plugins/, containing:
import "#mapbox/mapbox-sdk";
Then, in a page (say, myMap.vue), when I try:
var mapboxClient = mapboxSdk({ accessToken: MY_ACCESS_TOKEN });
which is the basic usage example in the documentation, I get:
mapboxSdk is not defined
in the console. This behavior extends to every single module I installed today, but is not the case for modules I had previously installed.
The reason why you're getting the error mapboxSdk is not defined is because there are a few issues with the way you've set up this plugin.
Docs here https://nuxtjs.org/docs/2.x/directory-structure/plugins/, they have some useful diagrams.
There are a couple of ways you can use this package.
Plugin
// ~/plugins/mapbox-sdk.js
import mapboxSdk from '#mapbox/mapbox-sdk'
export default (_ctx, inject) => {
// Exposing the mapboxSdk to your Nuxt app as $mapBox.
inject('mapBox', mapboxSdk)
}
Then in nuxt.config.js, same as you've already done.
plugins: [
...
"~/plugins/mapbox-sdk.js",
],
Then in your component myMap.vue
var mapboxClient = this.$mapBox({ accessToken: MY_ACCESS_TOKEN });
Directly in the component:
If you don't wish to use a plugin, the way that #kissu mentioned above https://stackoverflow.com/a/67421094/12205549 will also work.
Try adding this after the import to let Vue know that this method exists (in the same .vue file) at first
<script>
import mapboxSdk from '#mapbox/mapbox-sdk'
export default {
methods: {
mapboxSdk,
},
mounted() {
console.log('mapbox function >>', mapboxSdk)
},
}
</script>
Do you have it working in a .vue component at first ?

How to load CSS module with next.js

I'm trying to use the react-datepickermodule in my react App, but I'm having a hard time trying to load the css module of react-datepicker. I'm using next.js to render my app on server side.
I tried to implement a css loader provided by next to solve this kind of issue, but I got an error trying to build my app:
error
My component.js file:
import DatePicker from "react-datepicker";
import 'react-datepicker/dist/react-datepicker-cssmodules.css';
My nex.config.js file:
const withImages = require('next-images');
const withCSS = require('#zeit/next-css');
module.exports = withImages(
withCSS({
cssModules: true
})
);
Can you please tell me what is wrong with my imports or config ? Or what the 'minimize' property (displayed on the error message) means ?
Thanks a lot
EDIT: I ended up by importing css directly from
<link href="/static/react-datepicker.css" rel="stylesheet" />. Original post
Your css modules must end with .module.css.
To use CSS Modules, import a CSS file named *.module.css from any component. src
Import this way instead:
import styles from 'react-datepicker/dist/react-datepicker-min.module.css'
Try using Compose in your config file
I think you need to compose your plugins like so
// ... other imports
const compose = require('next-compose');
module.exports = compose([
withImages(),
withCss(),
{
webpack: (config) => {
/**some special code */
return config
}
}
]);
Details about the plugin can be found here
Your code is fine!
Instead of importing CSS into a component, try to import it into the page you wanted to use it on.
Next.js supports only custom page CSS imports.

How can I use a config file in React?

Let's say I have 5 jsx files and each file uses some config parameter.
My index.js file imports all of these 5 jsx files.
Instead of having my config data spread accross 5 files, is there a way for my jsx files to get the data from a global JS object which has loaded the data from a config file?
I've seen some examples, but I've not been able to get them to work.
JS6 import function | Example using webpack
Assuming ES6:
config.js
export const myConfig = { importantData: '', apiUrl: '', ... };
Then:
jsxFileOne.js, jsxFileTwo.js, ...
import { myConfig } from 'config.js';
There are other ways to import & export things globally leveraging webpack, but this should get you started.
If your project is built using Webpack, consider using node-env-file.
Example config file snippets:
development.env
API_SERVER_URL=https://www.your-server.com
webpack.config.js
const envFile = require('node-env-file');
...
const appSettingsFile = isDevBuild ? '/settings/development.env' : '/settings/production.env';
try {
envFile(path.join(__dirname + appSettingsFile));
} catch (error) {
console.log("Failed to read env file!: " + __dirname + appSettingsFile);
}
...
plugins: [
new webpack.DefinePlugin({
"process.env": {
API_SERVER_URL: JSON.stringify(process.env.API_SERVER_URL)
}
})
...
]
Inside your js/jsx code, you can now access process.env.API_SERVER_URL variable which will contain the required value.
It seems dotenv package is more popular, you can try this out as well.
Very old problem, that nobody took the time to solve, until now. I leave this for future readers because this is a top search result for configuration in React.
I created wj-config to deal exactly with this. Be sure to pay close attention to the React notes as you will need to enable top-level awaits in webpack, either by ejecting or using the #craco/craco NPM package.
You may also read this blog post that explains its use.

Categories

Resources