Webpack 2:像 jQWidgets 的 RequireJS 一样填充?
Webpack 2: shimming like RequireJS for jQWidgets?
我正在从 RequireJS 项目迁移到 Webpack。
后者对我来说是新的,我将其用作学习练习。
在 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 时发现的几个 guides/tutorials/takes,例如 this one and 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?$"
}]
},
很明显“imports/exports”的语法应该等同于 RequireJS 的“deps”和“exports”。
但是,当我在 index.ts 文件(应用程序根目录)中执行此操作时:
import "jqwidgets-framework/jqwidgets/jqxsplitter";
我的应用程序 运行 出现“jqxBaseFramework is undefined”错误。
我在 jQWidgets 的论坛上找到了对这个错误的引用,但是 none 的答案似乎真正解决了这个问题或包括 AOT 编译之类的东西,这不适用于我的情况,因为我不是使用 Angular.
我 posted 在 jQWidges 论坛上提出了同样的问题,但到目前为止还没有实际答案(现在持续两周),只有一个通用的答案说我应该在 jqxcore.js 之前加载jqxwhateverplugin.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 (knockout) 和 jqxBaseFramework。
所以现在我们告诉 webpack 每当加载 jqxknockout 时,它应该加载 jqxcore 模块并将其导出分配给一个名为 "jqxBaseFramework" 的模块局部变量并加载 knockout 模块并将其导出分配给一个名为 "ko"。
这实际上等同于将以下代码添加到 jqxknockout.js 脚本中:
var jqxBaseFramework = require("jqxcore");
var ko = require("knockout");
脚本现在可以再次执行,因为找到了这两个变量。
我添加了导出加载器来导出相同的内容,但现在 processed/augmented 来自 jqxknockout 的 jqxBaseFramework 变量。
jqxSplitter 通常只需要 jqxCore 即可工作,但我想始终将其与 knockout 一起使用。因此,我不是从 jqxCore 为 jqxSplitter 导入 jqxBaseFramework,而是从 jqxKnockout 获取它,因此所有部分都已就位。
所以现在当我将此代码添加到我所在的任何文件时:
import "jqwidgets-framework/jqwidgets/jqxsplitter";
Webpack 将需要 jqxknockout 及其导出,即 jqxBaseFramework,而这又将需要 jqxcore 和 knockout 等等,整个过程都非常漂亮。
希望这对某人有所帮助!
我正在从 RequireJS 项目迁移到 Webpack。 后者对我来说是新的,我将其用作学习练习。 在 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 时发现的几个 guides/tutorials/takes,例如 this one and 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?$"
}]
},
很明显“imports/exports”的语法应该等同于 RequireJS 的“deps”和“exports”。 但是,当我在 index.ts 文件(应用程序根目录)中执行此操作时:
import "jqwidgets-framework/jqwidgets/jqxsplitter";
我的应用程序 运行 出现“jqxBaseFramework is undefined”错误。 我在 jQWidgets 的论坛上找到了对这个错误的引用,但是 none 的答案似乎真正解决了这个问题或包括 AOT 编译之类的东西,这不适用于我的情况,因为我不是使用 Angular.
我 posted 在 jQWidges 论坛上提出了同样的问题,但到目前为止还没有实际答案(现在持续两周),只有一个通用的答案说我应该在 jqxcore.js 之前加载jqxwhateverplugin.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 (knockout) 和 jqxBaseFramework。 所以现在我们告诉 webpack 每当加载 jqxknockout 时,它应该加载 jqxcore 模块并将其导出分配给一个名为 "jqxBaseFramework" 的模块局部变量并加载 knockout 模块并将其导出分配给一个名为 "ko"。 这实际上等同于将以下代码添加到 jqxknockout.js 脚本中:
var jqxBaseFramework = require("jqxcore");
var ko = require("knockout");
脚本现在可以再次执行,因为找到了这两个变量。 我添加了导出加载器来导出相同的内容,但现在 processed/augmented 来自 jqxknockout 的 jqxBaseFramework 变量。
jqxSplitter 通常只需要 jqxCore 即可工作,但我想始终将其与 knockout 一起使用。因此,我不是从 jqxCore 为 jqxSplitter 导入 jqxBaseFramework,而是从 jqxKnockout 获取它,因此所有部分都已就位。 所以现在当我将此代码添加到我所在的任何文件时:
import "jqwidgets-framework/jqwidgets/jqxsplitter";
Webpack 将需要 jqxknockout 及其导出,即 jqxBaseFramework,而这又将需要 jqxcore 和 knockout 等等,整个过程都非常漂亮。
希望这对某人有所帮助!