我正在使用browserify使用CommonJS样式的依赖项来捆绑我的前端javascript.例如,我有:
$ = require('jquery/dist/jquery'); // v2.1.0-beta2
_ = require('underscore');
Backbone = require('backbone');
Run Code Online (Sandbox Code Playgroud)
但是,当browserify捆绑我遇到的依赖项时,会出现以下控制台错误:
Error: jQuery requires a window with a document
Run Code Online (Sandbox Code Playgroud)
看看jQuery代码,我看到它正试图this用于全局window.
(function( window, factory ) {
....
}(this, function( window ) {
Run Code Online (Sandbox Code Playgroud)
由于browserify包装了所有依赖项,因此this是一个object,而不是window.
有趣的是jQuery> = 2应该与CommonJS兼容.但是,问题是browserify如何包装依赖项.有人解决了这个问题吗?
我知道,Browserify并不是一个真正的DI框架,但是可以在单元测试期间"注入"或以某种方式伪造注入模拟数据到应用程序中吗?
例如,要测试功能:
var MyModel = require('./models/My.js');
function doSomething() {
// do something with model.
}
Run Code Online (Sandbox Code Playgroud)
与模拟My.js一样
describe('Do Something', function() {
beforeEach(function() {
// replace './models/My.js' with a Mock implementation.
});
it('with model', function() {
// ... test
});
})
Run Code Online (Sandbox Code Playgroud)
什么beforeEach功能?
所以我遇到了一个有趣的用例,我使用Browserify将我的所有资产捆绑在一个项目中,但是当某个应用程序内窗口需要加载大型外部(项目外部)模块时被访问.(这是一个由三个脚本组成的视频播放器模块,可在需要时异步拉入).
目前,uncalled object如果在Browserified app.js文件之前加载了requireJS模块,我会从错误中获得各种错误,如果在Browserified代码之后cannot find module加载,则会出现错误.
无论如何,我可以让Browserify和RequireJS在同一页面上很好地播放吗?我在失去理智!
一些简短的背景:我正在使用browserify和browserify-shim(和gulp来构建)来创建一个Web应用程序.在这个问题之前,我正在require从npm开始jquery,所以我没有任何问题.一旦我开始进行一些优化,我就意识到包含jQuery的程度有多大.所以现在我从带有脚本标签的CDN抓取jQuery并将其放在bundle.js文件之前.但是我在将jQuery声明为全局并且在browserify和browserify-shim中正确填充我的jQuery插件时遇到了问题.当我运行gulp进行构建时,我不断收到同样的错误:
[gulp] gulp-notify: [Compile Error] module "jquery" not found from "/Volumes/Chetan/Users/cshenoy/Projects/urbanstems-node/app/plugins/jquery.inview.js"
似乎browserify-shim并没有意识到jQuery是一个全局性的.
作为参考,我正在使用inview插件.
这是我的package.json及相关部分
"browser": {
"inview": "./app/plugins/jquery.inview.js"
},
"browserify-shim": {
"jquery": "global:jQuery",
"inview": {
"depends": [
"jquery"
]
}
}
Run Code Online (Sandbox Code Playgroud)
让我知道我还可以包含哪些内容来帮助诊断错误.
我正在使用browserify构建一个小角度应用程序ui-router.由于我不想使用服务器,我想使用angular $templateCache这样存储我的所有模板:
exports.templateCache = ["$templateCache", function($templateCache) {
'use strict';
$templateCache.put('partials/someState.html',
"myHtmlCode"
);
}];
Run Code Online (Sandbox Code Playgroud)
要填充缓存,我使用grunt查看我的partials文件夹,获取所有html并将其加载到缓存中grunt-angular-templates:
ngtemplates: {
myApp: {
cwd: 'dist/',
src: 'partials/**.html',
dest: 'src/js/templates/templates.js',
options: {
bootstrap: function(module, script) {
return 'exports.templateCache = ["$templateCache", function($templateCache) {\n' +
script +
'}];'
}
}
}
},
Run Code Online (Sandbox Code Playgroud)
然后我使用browersify将我所有的js组合在一起:
browserify: {
dist: {
files: {
'dist/js/app.js': [
'src/js/templates/**',
'src/app.js'
],
}
}
},
Run Code Online (Sandbox Code Playgroud)
这个工作到目前为止,但这个工作流对我来说看起来很笨重:我有一个中间步骤,我templates.js在我的src目录中创建文件,我在我的grunt文件中有硬编码的代码.
有没有办法更优雅地做到这一点?browserify是否附带内置解决方案来解决这个问题?
每次watchify检测到更改时,捆绑时间都会变慢.我的gulp任务肯定有问题.任何想法?
gulp.task('bundle', function() {
var bundle = browserify({
debug: true,
extensions: ['.js', '.jsx'],
entries: path.resolve(paths.root, files.entry)
});
executeBundle(bundle);
});
gulp.task('bundle-watch', function() {
var bundle = browserify({
debug: true,
extensions: ['.js', '.jsx'],
entries: path.resolve(paths.root, files.entry)
});
bundle = watchify(bundle);
bundle.on('update', function(){
executeBundle(bundle);
});
executeBundle(bundle);
});
function executeBundle(bundle) {
var start = Date.now();
bundle
.transform(babelify.configure({
ignore: /(bower_components)|(node_modules)/
}))
.bundle()
.on("error", function (err) { console.log("Error : " + err.message); })
.pipe(source(files.bundle))
.pipe(gulp.dest(paths.root))
.pipe($.notify(function() {
console.log('bundle finished in ' + (Date.now() - start) + …Run Code Online (Sandbox Code Playgroud) 如果有人对此事做过任何研究,我只是很好奇.
在我的工作地点,我们在每个项目/包中都有React,Bluebird,jQuery和Lodash.
我们使用webpack捆绑所有这些依赖项,但我不确定它是否真的值得...我认为很多这些脚本都会缓存在用户的浏览器上.
使用CDN并将这些包移出webpack包会减少构建时间并简化我们的构建过程.我们必须支持IE8,所以我们必须通过envify和ES3ify运行React.
有没有人研究过浏览器可以利用多少公共库的缓存?
我尝试编写这些代码
gulp.task('script', function() {
'use strict'
return gulp.src(['app.js', 'components/**/*.jsx'])
.pipe(babel())
.pipe(browserify())
.pipe(gulp.dest("dist"));
});
Run Code Online (Sandbox Code Playgroud)
但它显示了一些错误:
SyntaxError:
/Users/Zizy/Programming/learn-react-js/components/CommentBox.jsx:58
<div className="commentBox">
^
ParseError: Unexpected token
at wrapWithPluginError (/Users/Zizy/Programming/learn-react-js/node_modules/gulp-browserify/index.js:44:10)
Run Code Online (Sandbox Code Playgroud)
似乎.pipe(browserify())在gulp 之前没有改变jsx代码.但是,如果我只是删除.pipe(browserify())我发现确实改变了,只是不能让babel和browserify一起工作.
我知道也许我可以使用喜欢babelify或者browserify plugin for babel虽然,我只想找出原因.
我正在使用的命令是
browserify -t browserify-css src\app.js > bundle.js
Run Code Online (Sandbox Code Playgroud)
遍历的css文件最终作为bundle.js文件中的文本blob,最终在浏览器中加载时作为样式标记附加到头部.
是否可以输出bundle.js和bundle.css文件,其中bundle.css只是遍历的所有css文件的串联?
此示例中的src\app.js仅包含一个require
require( 'app.css' );
Run Code Online (Sandbox Code Playgroud) 我在我的项目中使用了browserify + gulp + babel,并且在ES7功能方面存在问题.这些是我安装的:
这是我的gulp代码:
gulp.task('build', () => {
let buildPath;
let destPath;
buildPath = `./src`;
destPath = `./dist`;
return browserify(`${buildPath}/app.js`)
.transform(babelify, {
presets: ["es2015", "es2016", "stage-0"],
plugins: ["transform-decorators-legacy", "transform-async-to-generator"]
})
.bundle()
.pipe(source('app.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(`${destPath}`));
});
Run Code Online (Sandbox Code Playgroud)
这是我的js代码:
import 'babel-polyfill';
// Async Functions
function wait(t) {
return new Promise((r) => setTimeout(r, t));
}
async function asyncMania() {
console.log('1'); …Run Code Online (Sandbox Code Playgroud) browserify ×10
javascript ×5
gulp ×3
jquery ×3
babeljs ×2
amd ×1
angularjs ×1
babel ×1
caching ×1
commonjs ×1
ecmascript-7 ×1
gruntjs ×1
node.js ×1
requirejs ×1
unit-testing ×1
watchify ×1
webpack ×1