问题
My goals are to include the following in my HTML file and have them all work properly:
index.html:
<script type="text/javascript" src="./vendor.js"></script>
<script type="text/javascript" src="./app.js"></script>
$(document).ready(function() {
// jQuery should be available as `window.$`
$(".myclass").doSomethingWithJquery();
}
<div class="row">
<h1 class="col-md-3 col-md-offset-3">
I should be able to use bootstrap, including bootstrap's javascript libraries, in my templates
</h1>
</div>
<!-- I should be able to use app.js, with its various require('module')
statements and attach rendered HTML to the DOM (I'm using React) -->
<div id="attach-app-js"></div>
Therefore:
- jQuery should be available as a global
$
variable. - Bootstrap's javascript functions should also work, as they're part of vendor.js
- My
app.js
should also work and not re-declare variables like$
that is already declared under global scope viavendor.js
.
See the files below. My current solution errors where I have $(".myclass").doSomethingWithJquery();
When my internet is off, I get the error:
Uncaught ReferenceError: $ is not defined
...which makes me think that (maybe) snackbarjs or another module is leaking jQuery to global scope.
Then, when I change the line in vendor.js
to: var $ = jQuery = require('jquery');
I get the error:
Uncaught ReferenceError: $ is not defined
but now it's getting called on the line $(document).ready(function.....
Third, if I comment out vendor.js
entirely, I get both errors:
Uncaught ReferenceError: $ is not defined
Uncaught ReferenceError: jQuery is not defined
How can I get this frontend setup to correctly shim variables when necessary in the global scope, and not if it's not necessary??
gulpfile.js:
.task('vendor', ['clean'], function() {
var b = browserify(package.paths.vendor);
var packages = getBowerPackageIds();
packages.forEach(function (id) {
var resolvedPath = bowerResolve.fastReadSync(id);
b.require(resolvedPath, {
// exposes the package id, so that we can require() from our code.
// for eg:
// require('./vendor/angular/angular.js', {expose: 'angular'}) enables require('angular');
// for more information: https://github.com/substack/node-browserify#brequirefile-opts
expose: id
});
});
return b
.bundle()
.pipe(source(package.dest.vendor))
.pipe(gulp.dest(package.dest.dist));
})
.task('js', ['clean', 'install'], function() {
var b = browserify(package.paths.app);
// mark vendor libraries defined in bower.json as an external library,
// so that it does not get bundled with app.js.
// instead, we will load vendor libraries from vendor.js bundle
getBowerPackageIds().forEach(function (lib) {
b.external(lib);
});
var w = watchify(b, watchify.args);
var file = package.dest.app,
dest = package.dest.dist;
w = w
.transform(reactify)
.transform(browserifyShim);
w.on('update', rebundle);
function rebundle() {
return w.
bundle()
.on('error', errorHandler)
.pipe(source(file))
.pipe(gulp.dest(dest))
.pipe(shell([
'python manage.py collectstatic --noinput'
], {
cwd: '../'
}))
// TODO: Do I need this?
.pipe(browserSync.reload({stream: true}));
}
return rebundle();
})
/**
* Running livereload server
*/
.task('server', ['clean', 'install', 'vendor', 'js', 'less'], function() {
browserSync({
proxy: "localhost:8000"
});
})
/**
* Compiling resources and serving application
*/
.task('serve', ['install', 'backup', 'clean', 'lint', 'less', 'vendor', 'js', 'server'], function() {
return gulp.watch([
package.paths.js,
package.paths.app,
package.paths.html,
package.paths.less,
package.paths.python
], [
'lint', 'less', browserSync.reload
]);
})
vendor.js:
$ = jQuery = require('jquery');
require('bootstrap');
require('snackbarjs');
package.json (browserify-shim
config):
"browserify-shim": {
"jquery": "$",
"bootstrap": {
"depends": [
"jquery:jQuery"
],
"exports": "bootstrap"
},
"jquery-cookie": {
"depends": [
"jquery:jQuery"
]
},
"eonasdan-bootstrap-datetimepicker": {
"depends": [
"jquery:jQuery",
"moment:moment",
"bootstrap:bootstrap"
],
"exports": "$.fn.datetimepicker"
},
"image-picker": {
"depends": [
"jquery:jQuery"
],
"exports": "$.fn.imagepicker"
},
"raven-js": {
"depends": [
"jquery:jQuery"
],
"exports": "raven-js"
},
"parsleyjs": {
"depends": [
"jquery:jQuery"
],
"exports": "parsleyjs"
}
},
"browser": {
"jquery": "./bower_components/jquery/dist/jquery.js",
"jquery-cookie": "./bower_components/jquery-cookie/jquery.cookie.js",
"image-picker": "./bower_components/image-picker/image-picker/image-picker.js",
"eonasdan-bootstrap-datetimepicker": "./bower_components/eonasdan-bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js",
"moment": "./bower_components/moment/moment.js",
"bootstrap": "./bower_components/bootstrap/dist/js/bootstrap.js",
"raven-js": "./bower_components/raven-js/dist/raven.js",
"parsleyjs": "./bower_components/parsleyjs/dist/parsley.js"
},
来源:https://stackoverflow.com/questions/32726088/how-do-i-properly-separate-my-app-js-and-vendor-js-bundles-using-browserify