我正在从broswerify切换到webpack。我为我的ajax调用创建了一个抽象。在该文件中,我有一些私有变量,我用它来设置URL和超时等。由于某种原因,它显示这些变量(和整个'闭包')未定义,导致一些奇怪的错误。这段代码与browserify完美配合。
这是我的webpack.config.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
devtool: 'source-map',
entry: path.resolve(__dirname, 'src', 'client', 'index.js'),
output: {
path: path.resolve(__dirname, 'public'),
publicPath: 'localhost:3002',
filename: 'bundle.js',
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader',
},
],
},
plugins: [
new webpack.DefinePlugin({
__API_URL__: JSON.stringify('http://localhost:3002/api'),
}),
],
};
这是我的api包装api.js
import request from 'superagent';
import store from './store';
import { system, account } from '../core/actions';
const API_URL = __API_URL__;
const TIMEOUT = 10000;
const _pendingRequests = {};
function getJwt() {
/**
* This retrieves the JSON Web Token from local or session storage
* We simply try both so that we don't have to subscribe to the store
* and make sure some flag is constantly updated. The reducer that handles
* the successful login will place the token in the proper place.
*/
let token = localStorage.getItem('JWT_TOKEN');
if (token) {
return 'Bearer ' + token;
}
token = sessionStorage.getItem('JWT_TOKEN');
if (token) {
return 'Bearer ' + token;
}
return null;
}
function addRequest(key, pendingRequest) {
_pendingRequests[key] = pendingRequest;
}
function abortPendingRequests(key) {
if (_pendingRequests.hasOwnProperty(key)) {
_pendingRequests[key]._callback = () => {
};
_pendingRequests[key].abort();
_pendingRequests[key] = null;
}
}
function digest(resolve, reject) {
return function consume(err, res) {
if (err && err.timeout === TIMEOUT) {
return store.dispatch(system.apiTimeout());
} else if (res.status === 401) {
return store.dispatch(account.logout());
} else if (!res.ok) {
return reject(res);
} else {
if (err) {
return reject(err);
} else {
return resolve(res.body);
}
}
};
}
export function get(actionType, resource) {
// abortPendingRequests(actionType);
return new Promise((resolve, reject) => {
const jwt = getJwt();
const url = `${API_URL}${resource}`;
const requested = request
.get(url)
.timeout(TIMEOUT);
if (jwt) {
requested.set('Authorization', jwt);
}
// addRequest(actionType, requested);
requested.end(digest(resolve, reject));
});
}
export function post(actionType, resource, data) {
// abortPendingRequests(actionType);
return new Promise((resolve, reject) => {
const jwt = getJwt();
const url = `${API_URL}${resource}`;
const requested = request
.post(url)
.timeout(TIMEOUT);
if (jwt) {
requested.set('Authorization', jwt);
}
if (data) {
requested.send(data);
}
// addRequest(actionType, requested);
requested.end(digest(resolve, reject));
});
}
export function put(actionType, resource, data) {
// abortPendingRequests(actionType);
return new Promise((resolve, reject) => {
const jwt = getJwt();
const url = `${API_URL}${resource}`;
const requested = request
.put(url)
.timeout(TIMEOUT);
if (jwt) {
requested.set('Authorization', jwt);
}
if (data) {
requested.send(data);
}
requested.end(digest(resolve, reject));
});
}
export function del(actionType, resource) {
// abortPendingRequests(actionType);
return new Promise((resolve, reject) => {
const jwt = getJwt();
const url = `${API_URL}${resource}`;
const requested = request
.del(url)
.timeout(TIMEOUT);
if (jwt) {
requested.set('Authorization', jwt);
}
// addRequest(actionType, requested);
requested.end(digest(resolve, reject));
});
}
有一些奇怪的评论是尝试调试问题的结果。但基本上,如果我在const _pendingRequests = {};
设置断点,则会显示API_URL
和TIMEOUT
正确设置。但是,如果我在const url =
中的;
$ {API_URL} $ {resource} export function get
设置了断点,则会将其显示为未定义,因为我将使用屏幕截图显示。
我只是注意到,在打破父范围之前,它正在打破子范围。我猜这与它有关,但我不知道如何改变这种行为。我在节点工作,所以我写了这个,就像我会为服务器写它。
这是我导入api.js
import * as api from '../../core/api';
import { endpoints } from '../../constants';
export const FETCH_LOOKUPS = 'FETCH_LOOKUPS';
export const FETCH_LOOKUPS_SUCCESS = 'FETCH_LOOKUPS_SUCCESS';
export function fetchLookupsSuccess(lookups) {
return {
type: FETCH_LOOKUPS_SUCCESS,
lookups,
};
}
export function asyncFetchLookups() {
return dispatch => {
return api.get(FETCH_LOOKUPS, endpoints.LOOKUP)
.then(lookups => dispatch(fetchLookupsSuccess(lookups)));
};
}
export const FETCH_LANG = 'FETCH_LANG';
export const FETCH_LANG_SUCCESS = 'FETCH_LANG_SUCCESS';
export function fetchLangSuccess(language) {
return {
type: FETCH_LANG_SUCCESS,
language,
};
}
export function asyncFetchLang() {
return dispatch => {
return api.get(FETCH_LANG, endpoints.LANGUAGE)
.then(language => dispatch(fetchLangSuccess(language)));
};
}
开始深入研究已编译的代码并找到了这个
function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TIMEOUT = exports.API_URL = undefined;
exports.get = get;
exports.post = post;
exports.put = put;
exports.del = del;
var _superagent = __webpack_require__(427);
var _superagent2 = _interopRequireDefault(_superagent);
var _store = __webpack_require__(430);
var _store2 = _interopRequireDefault(_store);
var _actions = __webpack_require__(444);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var API_URL = exports.API_URL = ("http://localhost:3002/api"); /**
* This file serves as a wrapper for any ajax requests that need to be made
* - contains a generic call for PUT, POST, GET and DELETE request
* - always attempts to append a JSON Web Token if present
* - keeps track of all pending requests and aborts identical requests
*/
var TIMEOUT = exports.TIMEOUT = 10000;
正如您所看到的,它最初将TIMEOUT和API_URL设置为未定义。然后,它会导出get
,post
等,然后设置TIMEOUT和API_URL,但这是在导出的get
已被访问之后。不确定为什么它将它们设置为未定义或如何解决此问题。
答案 0 :(得分:0)
根据您的需要(可能是导入),{% include 'modal_form.html' with modal_form_id="new-category" modal_form_title="Create a New Category" modal_form_method="POST" modal_form_action="/home/" form=category_form %}
函数babel可以首先转换get
函数并将其交给节点的require,然后将其删除。
然后你还没有编译get
。这看起来像一个边缘情况。
使用API_URL
而不是使用ES6 export
,而是使用module.exports
并使用节点require
导入它以解除此类错误。
如果此方法有效,请尝试使用import
而不是require
(并绕过export
而不是使用module.exports
)来缩小错误。
注意:这是一个提示/解决方法,而不是解决方案。您可以提供您提出要求的文件,这可能对其他人有用。
答案 1 :(得分:0)
问题与javascript完成解析之前调用的函数有关。 (仍然不确定原因)我发现的解决方法是将我的初始化函数附加到窗口对象,并在我的HTML正文的IIFE中调用它。