how can I use a external library in a grafana datasource plugin?
My plugin works but when i require the "mqtt" library which I have installed and saved to the package.json file I get the following error:
Plugin Error
Error loading http://localhost:3000/public/mqtt as "mqtt" from http://localhost:3000/public/plugins/myfirstplug/datasource.js
this is what my datasource.js head looks like:
define([
'mqtt'
'angular',
'lodash',
'../core_module',
'app/core/config',
],
function (mqtt,angular, _, coreModule, config) {
'use strict';
As I said the package.json already includes mqtt as dependency and ive put the mqtt folder in almost every folder which may be used as library folder manually , too.
How can I use a npm library in a grafana datasource plugin so that it works?
Thanks in advance!
I came across the same issue with including additional dependency for my plugin. I used this experimental plugin as boilerplate to tackle this issue:
You need to create a folder: src/external/
Add the compiled single file dist versions of your dependency under this folder like src/external/mqtt.js. (Actually even Grafana project has vendors in git repository)
In build task, you need to copy the files under your external folder, so your Gruntfile.js should be like this: https://github.com/NatelEnergy/grafana-plotly-panel/blob/master/Gruntfile.js
...
copy: {
...
externals: {
cwd: 'src',
expand: true,
src: ['**/external/*'],
dest: 'dist'
}
...
},
...
grunt.registerTask('default', ['clean', 'copy:src_to_dist', 'copy:pluginDef', 'copy:img_to_dist', 'copy:externals', 'babel']);
Now you can import the external library: import * as mqtt from './external/mqtt';
Related
in react using webpack every js files is bundle into a single bundle.js , for my normal html , css, js application for example , i am having 6 libraries. for an example consider
i am using jquery and bootstrap min versions. so if i reference two files the request will be two. so how can i make it into a single file. So there will be a single request.
like when i checked the file size is about in kb's and the request is processed within less that 1 or 2 seconds , like the chrome dev tools shows the time for to load also it parrallely loads the two files.
But how can i bundle the two librarys using webpack and get a single file that i can refer in my application.
i am a beginner to webpack
You need to import them in your entry point file and Webpack will handle the bundling. As you have worked with React, I assume you have basic command line skills.
You can read the Getting Started guide which bundles Lodash like how you are trying to bundle jQuery and Bootstrap.
First of install, ensure that you are installing jQuery, Bootstrap, and any other libraries using npm (or yarn, if you prefer):
# Install Webpack as a dev dependency
npm install webpack webpack-cli --save-dev
# Install dependencies (I've added Popper.js as Bootstrap requires it)
npm install jquery bootstrap popper.js
Create a folder called src and a file inside there called index.js. This is your entry point and Webpack will look for this file unless configured differently. Import the libraries like this:
import $ from 'jquery'
import 'bootstrap'
// Do something with jQuery
$(document).ready(() => console.log('Hello world!'))
Then run Webpack using npx:
npx webpack
A file named main.js should be created in a folder called dist that contains the bundled code. This is your output file. You can use a <script> tag in your HTML file to load this JavaScript:
<!-- assuming your index.html is in the dist folder -->
<script src='main.js'></script>
Once you get here, you can explore more advanced things like importing Bootstrap components individually, minifying code, multiple bundles, transpiling TypeScript, etc.
You will likely need to add a Webpack configuration file very soon as there is only so much that can be done using zero-config mode.
Good practice is to keep two sepearate bundles for the application logic and external libraries and in webpack this can be achieved by the following code,
app.js - appliation index file,
vendors.js - import all external libraries in this file
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
To get a single file, import vendors.js file inside app.js file and give entry key in webpack as
entry: './src/app.js'
Let us assume that you have the files in src directory. You can merge multiple files by specifying them in webpack.config.js to have a single named file as an output. I hope this is what you are looking for.
const path = require('path');
module.exports = {
entry: {
'bundle.js': [
path.resolve(__dirname, 'src/file1.js'),
path.resolve(__dirname, 'src/file2.js')
]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [{
exclude: /node_modules/
}]
}
};
As above, the two files "file1.js" and "file2.js" will be combined into a single file "bundle.js" and stored in "dist" directory.
You can also exclude node_modules by specifying a rule in module object of webpack configuration.
I use grunt-urequire plugin to compile my project-1's modules into single file (let's call it project-1.js). Config looks like this:
urequire: {
umd: {
template: 'UMD',
path: 'src',
dstPath: 'dist/umd'
},
dev: {
template: 'combined',
path: 'src',
main: 'Main',
dstPath: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
},
min: {
derive: ['dev', '_defaults'],
dstPath: 'dist/<%= pkg.name %>-<%= pkg.version %>.min.js',
optimize: 'uglify2'
},
_defaults: {
useStrict: true,
noConflict: true,
bundle: {
dependencies: {
exports: {
root: {
'Main': 'Project1'
}
}
}
}
}
}
Project-1 depends on project-2 which is also managed by grunt-urequire. In package.json:
"devDependencies": {
"project2": "^0.1",
...
}
Now I want to embed project-2 dependency into project-1 on build so that one could just do
<script src="project-1.js"></script>
in browser and don't include project-2 manually.
I know browserify supports this, but can I do it using urequire?
uRequire doesn't embed external dependencies (like jquery, underscore etc) into the combined.js file, unlike browserify which is the only option (as far as I know) and its also the default behavior of r.js.
This is partly intentional, cause its better to load (either using RequireJS or <script/>) these external libraries from a CDN: your user's browser might have already cached them last time it loaded your app (or someone else's app). And next time your myApp.js changes, it will download only that and not a monolithic bundle that contains all the same external libs all over again.
uRequire actually goes a long way to make sure these are loaded externally, whether on nodejs (using plain node's require) or the browser, using AMD or the exported global properties (like window.$, window._ or whatever the external library is mapped to).
I would imagine you can easily override this behavior: just place project-2.js whenever you build it onto the source folder of project-1, and just use it in project-1 as a normal dependency.
Alternatively you can again build/convert all project-2 files as AMD (not combined) into the source folder of project-1 and use them as being part of it.
Finally, you could just symlink the project-2 source into project-1, its supported on unix/linux for decades and also on Windows 7 onwards. Then uRequire will convert the sources from both projects only once and build as a single output.
Ideally I would like to have virtual sources (see https://github.com/anodynos/uRequire/issues/40) so you can leave both projects separate (i.e not build one into the other), but build both as one output.
If you want to version the 2 projects on the same git repository because they are updated together and have the same release lifecycle, you can have a build script in 2 parts:
First part is to compile project2 (project2/src)
Second part is to compile project1 (project1/src)
During the compilation of project2, you can copy the distributed JS of project2 into project1/src so that it is automatically.
If you have different release lifecycles, you can use some grunt tool to download the dependency from a CDN / NPM and put it into the project1/src folder before packaging project 1
This is somehow what is done by Browserify by using NPM, but it would probably be the same with Bower, components or custom JS code to download the dependencies. I would recommend using a tool like NPM however because it also download transitive dependencies (if one day project2 introduces a dependency, you won't have to touch project1 build...)
Finally, I don't know uRequire but maybe you could be inspired by this project, which embeds dependencies in the packaged version (eventie)
I'm using Bower and Grunt on my application. Thus, I have a bower_components directory with several sub-directories, containing all my dependencies.
Currently, on my Gruntfile.js, I have something like that:
copy: {
bower: {
files: [
{
expand: true,
cwd: 'app/',
dest: 'dist/',
src: [ 'bower_components/**/*' ]
}
]
},
...
which means that I copy everything under bower_components to finally package my application. The problem is that I don't need everything under this directory, for example there are non minified JS, resources, documentation, etc.
Is there a way to make an intelligent filter that only takes the required elements in the bower_components directory (i.e. without selecting the files myself)?
Am I missing some good practices regarding the packaging of an application with bower and grunt?
Thanks
ps: as it is for an intranet application, I prefer not to use CDN.
I'm configuring my Gruntfile and I'm stuck on something I feel should be possible but I'm not able to find the right configuration for it. I'm trying to copy my bower components to my dist on build with the grunt-contrib-requirejs module. The part I'm stuck on is keeping the folder structure in tact when copying to dist.
My app's basic structure, and dist/ should build the same way
Gruntfile.js
app/
- assets/
- bower_components/
- js/
- img/
- etc/
- index.html
Currently, I define each file in the copy module and it copy's them all over
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: 'app',
dest: 'dist',
src: [
'*.{ico,png}',
'.htaccess',
'partials/**/*',
// Bower Components
'assets/bower_components/requirejs/require.js',
'assets/bower_components/fastclick/lib/fastclick.js',
'assets/bower_components/jquery/dist/jquery.min.js',
'assets/bower_components/modernizr/modernizr.js'
]
}]
}
},
But I want to eliminate this and use the paths I've already defined in main.js to copy these files over. Less hardcoded stuff, more automation.
My require task
requirejs: {
dist: {
options: {
mainConfigFile: app + '/assets/js/main.js',
dir: dist + '/assets/js',
optimize: 'uglify',
paths: {
modernizr: 'empty:',
jquery: 'empty:',
fastclick: 'empty:'
}
}
}
},
This current configuration combined with copy moves them all over properly. If I could eliminate the paths property all together and use directory properties only that would be great. If I have to copy my paths from my main.js into here thats ok... if it's the only way to do it.
Let me know if you need any more info!
The JS files in your bower directory should be included in the optimized output of requirejs, as long as they are configured and referenced in your require js app. If they're not referenced as dependencies, I don't think they get included.
The ico, png, htaccess and other files may need to be copied over manually.
Depending on your partials, the text plugin and hbs plugin could compile those into the optimized file I think.
I think defining empty: in paths are for using network resources (e.g. when using CDNs instead of using local bower libraries), so the paths config is probably unnecessary
I'm using the RequireJS optimiser to minify and concatenate my code. At the moment r.js doesn't minify a lot of my scripts because of the nested dependencies.
I want to include nested dependencies for:
All dependencies inside: 'js/services'
All nested dependencies for a list of specific JavaScript files
Note: I do realise that there is the option findNestedDependencies: true but this looks for absolutely every dependency across all JavaScript files in the app where as I only want to do this for certain JavaScript files and folders as I have a set of files which are always used on every page/view.
My current build file looks like:
({
baseUrl: '../static/js',
mainConfigFile: '../static/js/main.js',
name: 'main',
out: '../static/js/scripts.min.js',
paths: {
requireLib: 'vendor/require/require.min'
},
include: 'requireLib'
})
I have been following this tutorial to get the optimiser running:
http://www.youtube.com/watch?v=m6VNhqKDM4E
You can use include to specify all dependencies you want to force into the output file:
// ...
include: ['requireLib', 'js/services/dep1', 'js/services/dep2'],
// ...
I don't think there's a way to include entire folder (something like "js/services/*"), though.
Since in my project I had many dynamic dependencies I wanted to include in the output I ended up creating an "js/services/_all.js" module which lists files in its directory, for example:
define([
'./dep1',
'./dep2'
],
function () {
// this module imports all modules from current folder so
// there's no need to list every single file in the build config
});
and then configuring r.js with:
// ...
include: ['requireLib', 'js/services/_all'],
// ...