Webpack 2:为jQWidgets提供像RequireJS一样的匀场?
我正在从RequireJS项目迁移到Webpack。 后者对我来说是新的,我将其用作学习练习。 在RequireJS我可以这样注册的东西:Webpack 2:为jQWidgets提供像RequireJS一样的匀场?
shim: {
'jqxcore': {
exports: "$",
deps: ["jquery"]
},
'jqxtree': {
exports: "$",
deps: ["jquery", "jqxcore"]
},
'jqxbutton': {
exports: "$",
deps: ["jquery", "jqxcore"]
},
'jqxsplitter': {
exports: "$",
deps: ["jquery", "jqxcore"]
},
'jqxmenu': {
exports: "$",
deps: ["jquery", "jqxcore"]
}
}
,然后只需要“jqxsplitter”比如,像这样:
import "jqxsplitter"
之类的东西将被正确注册和加载。 现在我正在看几个指南/教程/我发现从RequireJS迁移到Webpack时发现的,例如this one和this之一。 所以以下这些见解,我想在我webpack.config.js是这样的:
"use strict";
// Required to form a complete output path
const path = require("path");
// Plagin for cleaning up the output folder (bundle) before creating a new one
const CleanWebpackPlugin = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
// Path to the output folder
const bundleFolder = "./wwwroot/";
// Path to the app source code
const appFolder = "./app/";
module.exports = {
// Application entry point
entry: {
main: appFolder + "index.ts",
vendor: [
"knockout",
"jquery",
"jqxcore"
],
jqxsplitter: "jqxsplitter"
},
// Output file
output: {
filename: "[name].js",
chunkFilename: "[name].js",
path: path.resolve(bundleFolder)
},
module: {
rules: [{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/
}, {
test: /\.html?$/,
loader: "html-loader" //TODO: file-loader?
}],
loaders: [{
test: /jqxcore/,
loader: "imports?jquery!exports?$"
}, {
test: /jqxsplitter/,
loader: "imports?jquery,jqxcore!exports?$"
}]
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
alias: {
"jqxcore": "jqwidgets-framework/jqwidgets/jqxcore",
"jqxsplitter": "jqwidgets-framework/jqwidgets/jqxsplitter"
}
},
plugins: [
new CleanWebpackPlugin([bundleFolder]),
new HtmlWebpackPlugin({
filename: "index.html",
template: appFolder + "index.html",
chunks: ["main", "vendor"]
}),
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
filename: "vendors.js",
minChunks: Infinity
})
],
devtool: "source-map"
};
相关部分(我认为)是
module: {
loaders: [{
test: /jqxcore/,
loader: "imports?jquery!exports?$"
}, {
test: /jqxsplitter/,
loader: "imports?jquery,jqxcore!exports?$"
}]
},
这是很清楚如何的“语法进口/出口“应该等于RequireJS的”deps“和”exports“。 不过我做这在我的index.ts文件(应用程序根)时:
import "jqwidgets-framework/jqwidgets/jqxsplitter";
我得到运行我的应用程序时,“jqxBaseFramework是未定义”的错误。 我在jQWidgets的论坛上发现了对这个错误的引用,但是没有一个答案似乎真的解决了这个问题,或者包含了AOT编译之类的东西,它不适用于我的情况,因为我没有使用Angular。
我已经posted同样的问题在jQWidges论坛,但至今没有实际的答案(现在要在两周),只有一个通用的答案说jqxwhateverplugin.js之前,我应该加载jqxcore.js。 嗯,显然,这就是我正在尝试使用匀场完成的。
任何想法?
那么我结束了深潜,并为自己找出了答案。 如果有人发现自己身处相同或相似的小船,这里的解决方案就是如此。
如果您美化jQWidgets脚本文件jqxcore.js,您会看到它创建了一个通常为名为“jqxBaseFramework”的全局变量,该变量当然不会全局公开,只能在其自己的模块中显示。这就是问题所在。
的解决方案是使用这种配置:
module: {
rules: [{
test: /jqxcore/,
use: "exports-loader?jqxBaseFramework"
}, {
test: /jqxknockout/,
use: ["imports-loader?jqxBaseFramework=jqxcore,ko=knockout", "exports-loader?jqxBaseFramework"]
}, {
test: /jqxsplitter/,
use: "imports-loader?jqxBaseFramework=jqxknockout"
}]
},
resolve: {
...
alias: {
"knockout": "knockout/build/output/knockout-latest",
"jqxcore": "jqwidgets-framework/jqwidgets/jqxcore",
"jqxknockout": "jqwidgets-framework/jqwidgets/jqxknockout",
"jqxsplitter": "jqwidgets-framework/jqwidgets/jqxsplitter"
}
},
我想,一旦点击,这一切才有意义。 jqxcore模块现在将导出其具有相同名称的jqxBaseFramework变量。
我加入了淘汰赛的支持,而在它。 jqxknockout期望两个全局变量正常工作:ko(敲除)和jqxBaseFramework。 所以现在我们告诉webpack,每当jqxknockout被加载时,它应该加载jqxcore模块,并将其输出分配给一个名为“jqxBaseFramework”的模块局部变量,并加载淘汰赛模块并将其输出分配给模块局部变量“ko ”。 这实际上等同于将以下代码预先添加到jqxknockout。js脚本:
var jqxBaseFramework = require("jqxcore");
var ko = require("knockout");
脚本现在可以再次执行,因为找到了这两个变量。 我添加了导出加载器来导出相同的,但现在处理/增强jqxBaseFramework变量从jqxknockout。
jqxSplitter通常只需要jqxCore工作,但我想总是用它来淘汰。所以我没有从jqxSplitter的jqxCore中导入jqxBaseFramework,而是从jqxKnockout中获得它,所以所有的部分都已经到位。 所以现在当我将此代码添加到我在任何文件:
import "jqwidgets-framework/jqwidgets/jqxsplitter";
的WebPack需要jqxknockout和它的出口,是jqxBaseFramework,这反过来将需要jqxcore和基因敲除等瞧,整个事情精美地连接起来。
希望这可以帮助别人!