我正在尝试使用Webpack,并尝试使用Tables in the visual formatting model中的说明,提供或采取一些自定义内容。
这是一个简单的代码,真的,但我对这个错误感到非常困惑,觉得这是我错过的傻事。
我定义了两个ES6类,每个类对应一个Handlebars模板,我的应用程序的入口点应该用它们的内容替换索引文件中的占位符HTML:
入口点:
import './bloj.less'
// If we have a link, render the Button component on it
if (document.querySelectorAll('a').length) {
require.ensure([], () => {
const Button = require('./Components/Button.js');
const button = new Button('9gag.com');
button.render('a');
}, 'button');
}
// If we have a title, render the Header component on it
if (document.querySelectorAll('h1').length) {
require.ensure([], () => {
const Header = require('./Components/Header.js');
new Header().render('h1');
}, 'header');
}
索引:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>My title</h1>
<a>Click me</a>
<script src="build/bloj.js"></script>
</body>
</html>
按钮:
import $ from 'jquery';
import './Button.less';
export default class Button {
constructor(link) {
this.link = link;
}
onClick(event) {
event.preventDefault();
alert(this.link);
}
render(node) {
const text = $(node).text();
var compiled = require('./Button.hbs');
// Render our button
$(node).html(
compiled({"text": text, "link": this.link})
);
// Attach our listeners
$('.button').click(this.onClick.bind(this));
}
}
标题
import $ from 'jquery';
import './Header.less';
export default class Header {
render(node) {
const text = $(node).text();
var compiled = require('./Header.hbs');
// Render the header
$(node).html(
compiled({"text": text})
);
}
}
可悲的是,它不起作用,我在显示页面时得到这两个错误:
Uncaught TypeError: Header is not a constructor
Uncaught TypeError: Button is not a constructor
我可以缺少什么?
这是我的webpack配置:
var path = require('path');
var webpack = require('webpack');
var CleanPlugin = require('clean-webpack-plugin');
var ExtractPlugin = require('extract-text-webpack-plugin');
var production = process.env.NODE_ENV === 'production';
var appName = 'bloj';
var entryPoint = './src/bloj.js';
var outputDir = './build/';
var publicDir = './build/';
// ************************************************************************** //
var plugins = [
//new ExtractPlugin(appName + '.css', {allChunks: true}),
new CleanPlugin(outputDir),
new webpack.optimize.CommonsChunkPlugin({
name: 'main',
children: true,
minChunks: 2
})
];
if (production) {
plugins = plugins.concat([
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.MinChunkSizePlugin({
minChunkSize: 51200 // 50ko
}),
new webpack.optimize.UglifyJsPlugin({
mangle: true,
compress: {
warnings: false // Suppress uglification warnings
}
}),
new webpack.DefinePlugin({
__SERVER__: false,
__DEVELOPMENT__: false,
__DEVTOOLS__: false,
'process.env': {
BABEL_ENV: JSON.stringify(process.env.NODE_ENV)
}
})
]);
}
module.exports = {
entry: entryPoint,
output: {
path: outputDir,
filename: appName + '.js',
chunkFilename: '[name].js',
publicPath: publicDir
},
debug: !production,
devtool: production ? false : 'eval',
module: {
loaders: [
{
test: /\.js/,
loader: "babel",
include: path.resolve(__dirname, 'src'),
query: {
presets: ['es2015']
}
},
{
test: /\.less/,
//loader: ExtractPlugin.extract('style', 'css!less')
loader: "style!css!less"
},
{
test: /\.html/,
loader: 'html'
},
{
test: /\.hbs/,
loader: "handlebars-template-loader"
}
]
},
plugins: plugins,
node: {
fs: "empty" // Avoids Handlebars error messages
}
};
答案 0 :(得分:47)
我能错过什么?
Babel将默认导出分配给default
属性。因此,如果您使用require
导入ES6模块,则需要访问default
属性:
const Button = require('./Components/Button.js').default;
答案 1 :(得分:8)
我意识到你已经有了答案。但是我有一个类似的问题,我找到了答案。开始我自己的问题并回答它似乎很奇怪。 所以我只想把它留在这里。
我遇到了同样的错误。但是,我设法通过改变我的
来解决它export default {Class}
到
export default Class
我不知道为什么我将Class包装在一个对象中,但我记得曾经在某个地方看过它,所以我才开始使用它。
因此,返回一个类而不是默认返回一个类,它返回了一个像{Class: Class}
这样的对象。
这完全有效,但它会打破webpack + babel。
export default
意味着只有1个导出。 javascript-object可以包含许多属性。这意味着它可以有多个导出。 (见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)。
对于多个导出,请使用:export {definition1, definition2}
。
用例:我在我创建了一个导出不同类型编辑器的库的情况下使用过它(虽然底层代码是相同的,编辑器的外观会根据你使用的导出而改变)。
答案 2 :(得分:6)
您可以在导出班级后立即放置export var __useDefault = true;
。
export default class Header {
...
}
export var __useDefault = true;
答案 3 :(得分:1)
这不是这个问题的问题,但由于某些原因,babel不会在同一个文件中提升类。
因此,如果您在文件顶部声明了您的班级Token
,并稍后再写new Token()
,那么它就会运行。
如果在构造函数调用后声明了类,则 xxx不是构造函数错误
答案 4 :(得分:0)
虽然这不是导致您遇到特定问题的原因,但在尝试使用ES6 export
和import
语法的现有节点应用程序中删除babel时遇到了类似的问题,因此这篇文章是为了帮助其他人在未来努力解决这个问题。
Babel将解决一个模块与另一个模块之间的任何循环依赖关系,因此您可以放弃使用ES6的export
和import
。但是,如果您需要摆脱babel并使用本机节点,则需要将exports
和require
替换为const B = require('B');
class A {
constructor() {
this.b = new B();
}
}
module.exports = A;
。这可以重新引入babel在后台处理的潜在循环引用问题。如果您发现自己处于这种情况,请在代码中查找如下所示的区域:
档案A:
const A = require('A'); // this line causes the error
class B {
constructor() {
this.a = new A();
}
}
module.exports = B;
档案B:
B
根据您的代码结构,有几种不同的方法可以解决此问题。最简单的方法可能是将A
引用传递给A
,而不是创建类A
的新实例。您还可以在加载* How to I import chart.js? I'm currently using their CDN
* If that is impossible, what other charting library *is* importable?
时动态解析引用。有许多其他选择,但这是一个开始的好地方。
答案 5 :(得分:0)
我能够通过将babel-plugin-add-module-exports
添加到.babelrc
文件中来解决此问题
npm install babel-plugin-add-module-exports --save-dev
{
"presets": ["@babel/env"],
"plugins": ["add-module-exports"]
}
这增加了
module.exports = exports.default;
使用babel编译类时,转到最后一行。