I just wondered if it is possible to make systemjs use require("remote").require("nodemodule"), if system js can't find the module in its own registry?
I think something like this mechanism is already working when using electron with typescript and commonjs modules...
Has someone already solved that struggle?
Finally after some time I found a working solution:
var node_modules = ["child_process","fs"];
var fetch = System.fetch;
window.remote=require("remote");
System.fetch = function () {
var promise= fetch.apply(System,arguments);
return promise.then(function (js) {
for(var m of node_modules){
var requireExpression = 'require("'+m+'");';
var remoteRequire = 'remote.require("'+m+'");'
js=js.replace(requireExpression,remoteRequire);
}
return js;
});
}
System.import("aurelia-bootstrapper");
Just add all imported node_modules to the array and things are fine
Related
I'm trying to build pdf.js in order to embed the viewer into an app I'm working on.
I want to build the viewer by hand so it can be included in the application that is getting packaged by webpack.
The application entrypoint, index.js, has the line
import viewer from 'pdfjs-dist/web/pdf_viewer';
This results in the viewer being included in the transpiled app code, however the pdf.js viewer uses System.js to load modules that it needs to run.
In the compiled version that Mozilla serves, the code has been transpiled to not use System.js; see view-source:https://mozilla.github.io/pdf.js/web/viewer.js in the the webViewerLoad function on line 3774.
function webViewerLoad() {
var config = getViewerConfiguration();
window.PDFViewerApplication = pdfjsWebApp.PDFViewerApplication;
pdfjsWebApp.PDFViewerApplication.run(config);
}
This differs from the non-transpiled source that can be found on https://github.com/mozilla/pdf.js/blob/master/web/viewer.js#L178, and the source map for the Mozilla hosted viewer retains these SystemJS lines.
function webViewerLoad() {
let config = getViewerConfiguration();
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {
Promise.all([
SystemJS.import('pdfjs-web/app'),
SystemJS.import('pdfjs-web/genericcom'),
SystemJS.import('pdfjs-web/pdf_print_service'),
]).then(function([app, ...otherModules]) {
window.PDFViewerApplication = app.PDFViewerApplication;
app.PDFViewerApplication.run(config);
});
} else {
window.PDFViewerApplication = pdfjsWebApp.PDFViewerApplication;
pdfjsWebApp.PDFViewerApplication.run(config);
}
}
What I want to know is how this was achieved, and how to replicate the configuration to build this.
The production viewer.js has been compiled with webpack. In gulpfile.js you will find the following block:
function createWebBundle(defines) {
var viewerOutputName = 'viewer.js';
var viewerFileConfig = createWebpackConfig(defines, {
filename: viewerOutputName,
});
return gulp.src('./web/viewer.js')
.pipe(webpack2Stream(viewerFileConfig));
}
In my case I simply installed pdfjs-dist and imported pdfjs-dist/web/pdf_viewer. Building with webpack worked fine. Getting the web worker to work right required some extra effort.
I'm trying to use Webpack to create a couple of simple modules in an ASP.NET MVC 5 Visual Studio 2015 project. Following instructions on the Webpack site, I downloaded the latest version of Node.js. Then using the Node command prompt, changed to my project's folder. There, I ran this command to install Webpack locally:
npm install webpack --save-dev
It created a package.json file in the root of my project:
{
"devDependencies": {
"webpack": "^2.4.1"
}
}
Note that the project already has jQuery and Bootstrap as bundles via the BundleConfig.cs, which are then referenced on _Layout.cshtml; hence they're available on all pages of the app.
Now I'd like to create a very simple test to see how to create and require modules using Webpack; once I understand it better, I can add more complex modules. I've been reading about code-splitting: https://webpack.js.org/guides/code-splitting-async/ but it's still not clear how you do this.
The function test requires function isEmpty. I'd like to define isEmpty as a module and then use it with test.
var test = function(value){
return isEmpty(value);
};
var isEmpty = function(value) {
return $.trim(value).length === 0 ? true : false;
};
This article has been helping: http://developer.telerik.com/featured/webpack-for-visual-studio-developers/
The Webpack documentation mentions import() and also require.ensure(). How do I use Webpack to modularize the isEmpty code and then use it?
Webpack allows you to use the commonJS approach for dependency management which Node.js uses, so if you have experience with Node.js it's very similar.
If not have a look at this article on the module system or the spec for a description of the module system.
For this problem I will assume all files are in the same directory. I think you will need to first move the isEmpty code into a separate file maybe isEmpty.js and change it's structure a bit so that it looks like this:
module.exports = function(value) {
return $.trim(value).length === 0 ? true : false;
};
then your test function can be moved into a separate test.js file and you can require the isEmpty module and use it like this:
var isEmpty = require('./isEmpty');
var test = function(value){
return isEmpty(value);
};
You will probably have to do something about the dependency on $ (I'm guessing jquery?) but I think that can be handled with shimming
If you have a number of functions you can do something like:
someFunctions.js
var self = {};
self.Double = function(value){
return value*2;
}
self.Triple = function(value){
return value*3;
}
module.exports = self;
useFunctions.js
var useFunctions = require('./someFunctions');
var num = 5;
console.log(useFunctions.Double(num));
console.log(useFunctions.Triple(num));
I am trying to switch from using browserify to webpack. One thing browserify handled nicely was dependency management inside dependencies. Let me give an example:
Main app project:
var util1 = require('shared-components/util1');
var util2 = require('shared-components/util2');
Inside shared-components/util1.js
var util2 = require('../util2');
Browserify would realize that the reference to util2 in both scenarios was the same but it appears that Webpack does not which creates duplicate entries for util2.
Is there a configuration setting or plugin I can use to resolve this?
Try new webpack.optimize.DedupePlugin(). See the docs for more info.
I have been prototyping a JavaScript application and now I want to move to a more robust setup using browserify and managing dependencies with require.
Currently I have the following files in my application:
chart.js
form.js
highcharts-options.js
vendor/
highcharts.js
jquery.js
highcharts-options.js is basically a list of constants, while chart.js looks like this...
var myChart = {
setup: function(data) { ... this.render(data); },
render: function(data) { ... }
},
and form.js looks like this:
var myForm = {
setup: function() { button.onclick(_this.getData(); },
getData: function() { // on ajax complete, callChart },
callChart: function() { myChart.setup(data); }
};
myForm.setup();
And then I have an index.html page that imports everything as follows:
<script src="/js/vendor/highcharts.js"></script>
<script src="/js/vendor/jquery.js"></script>
<script src="/js/highcharts-options.js"></script>
<script src="/js/chart.js"></script>
<script src="/js/form.js"></script>
So now I want to move this to a more modern setup with browserify.
I have deleted the vendor directory and instead created an index.js file and a package.json file, so now my directory structure looks like this:
index.js
package.json
chart.js
form.js
highcharts-options.js
node_modules/
I have run npm i --save highcharts-browserify and npm i --save jquery and that has saved these modules to package.json and installed them in node_modules. I've also added a build task in package.json: browserify index.js -o bundle.js. And in my front-end template I know just have:
<script src="/js/bundle.js"></script>
So far so good.
My question is what to put into my index.js file, because I'm not sure how to import the files that I already have. So far I've got this:
var $ = require('jquery');
var HighCharts = require('highcharts-browserify');
var options = require('highcharts-options');
var myChart = require('chart');
var myForm = require('form');
myForm.setup();
But when I try to build this, I get:
Error: Cannot find module 'chart' from '/mypath/static/js/app'
It looks like require doesn't know how to find this file, or how to import it, which is not surprising given that this is all total guesswork on my part.
How should I adapt these files to work in a more modular way? Am I on the right lines, or is this completely the wrong approach? I'm not even sure what I should be Googling for.
(NB: Eventually I want to refactor chart.js and form.js to use Backbone, but I need to work one step at a time.)
You are very close!
First, the way to reference a module in the same directory is to say:
var myChart = require('./chart');
Without the leading path component, require will look in your npm package directory.
Second, you need to export the variables in the modules so that they can be used elsewhere. So your form module needs to look something like this:
var myForm = {
setup: function() { button.onclick(_this.getData(); },
getData: function() { // on ajax complete, callChart },
callChart: function() { myChart.setup(data); }
};
myForm.setup();
module.exports = myForm;
I just finished struggling with this error for a while, I'll post my solution in case anyone else runs into the same issue I did. It seems that Browserify sometimes can't find local modules depending on where the require goes. This code didn't work:
window.Namespace = {
foo: new require('./foo.js')()
};
but this worked fine:
var Foo = require('./foo.js');
window.Namespace = {
foo: new Foo()
};
My folder structure:
dashboard >
components >
accounts > accounts.js, accountsDirectives.js
dash > dashApp.js
settings > settings.js, settingsDirectives.js
etc...
My function in the Gulpfile
function compile_js(minify, folder) {
var jsLibs = gulp.src('client/'+folder+'/_sources/js/libs/*.js');
var jsPlugins = gulp.src('client/'+folder+'/_sources/js/plugins/*.js');
var jsCustom = gulp.src('client/'+folder+'/_sources/js/custom/*.js');
var jsComponents = gulp.src('client/'+folder+'/components/*.js');
// Order the streams and compile
return streamqueue({ objectMode: true },
jsLibs,
jsPlugins,
jsCustom,
jsComponents
)
.pipe(concat(folder+'.module.js'))
.pipe(gulpif(minify, uglify()))
.pipe(gulp.dest('client/'+folder+'/assets/js'));
};
The issue is this line, that targets the components directory:
var jsComponents = gulp.src('client/'+folder+'/components/*.js');
I've also tried /components/**/*.js but still doesn't work.
I found this answer here, which they talk about symlinks, but I want to avoid using that. 1) It seems like a hack, and 2) this requires all current and future devs to create the exact symlinks on their computers as well.
Is there another way to easily target and compile all js files in a directory with sub directories?
Have you tried creating the paths first and then using the variables in your gulp.src arguments? Im also curious if since you are minifying them, why don't you just grab all the files for some of them with something like :
var someVar = gulp.src('client/'+folder+'/_sources/js/**/*.js');
vs
var jsPlugins = gulp.src('client/'+folder+'/_sources/js/plugins/*.js');
var jsCustom = gulp.src('client/'+folder+'/_sources/js/custom/*.js');