diff --git a/packages/adapter-webpack/package.json b/packages/adapter-webpack/package.json
index 679bf57a..2ff5d559 100644
--- a/packages/adapter-webpack/package.json
+++ b/packages/adapter-webpack/package.json
@@ -28,7 +28,6 @@
"dependencies": {
"@uiengine/util": "2.3.1",
"globby": "10.0.1",
- "htmlescape": "1.1.1",
"object-hash": "^1.3.1",
"require-from-string": "2.0.2"
},
@@ -49,7 +48,8 @@
"vue-template-compiler": "2.6.10",
"webpack": "4.39.2",
"webpack-merge": "4.2.1",
- "webpack-node-externals": "1.7.2"
+ "webpack-node-externals": "1.7.2",
+ "webpack-virtual-modules": "^0.1.11"
},
"optionalDependencies": {
"parse-prop-types": "0.3.0",
diff --git a/packages/adapter-webpack/src/deps.js b/packages/adapter-webpack/src/deps.js
index 428fe0f6..8b7039a5 100644
--- a/packages/adapter-webpack/src/deps.js
+++ b/packages/adapter-webpack/src/deps.js
@@ -18,12 +18,13 @@ async function getDependencyFiles (options, filePath, cache) {
// cache the promises so that files do not get added multiple times
const promise = new Promise((resolve, reject) => {
buildQueued(options, filePath)
- .then(({ serverChunk, clientChunk }) => {
- const chunk = serverChunk || clientChunk
+ .then(({ serverComponentChunk, clientComponentChunk }) => {
+ const chunk = serverComponentChunk || clientComponentChunk
// https://webpack.js.org/api/stats#chunk-objects
- const filePaths = chunk ? chunk.modules.map(({ id }) => {
- const mod = id.split('?!').pop().replace(/\?.*$/, '')
+ const filePaths = chunk ? chunk.modules.map(({ id, name }) => {
+ const ident = typeof id === 'number' ? (name.match(/\s([^\s]*)/g) || ['']).shift().trim() : id
+ const mod = ident && ident.split('?!').pop().replace(/\?.*$/, '')
let modulePath
if (mod) modulePath = mod.startsWith('.') ? path.resolve(mod) : require.resolve(mod)
return modulePath && crossPlatformPath(modulePath)
diff --git a/packages/adapter-webpack/src/index.js b/packages/adapter-webpack/src/index.js
index 1f70ad37..102e0bfc 100644
--- a/packages/adapter-webpack/src/index.js
+++ b/packages/adapter-webpack/src/index.js
@@ -1,5 +1,4 @@
-
-const htmlescape = require('htmlescape')
+const { FileUtil: { requireUncached } } = require('@uiengine/util')
const { extractDependentFiles, extractDependencyFiles } = require('./deps')
const { buildSetup, buildQueued, getExtractProperties } = require('./util')
@@ -18,7 +17,7 @@ async function setup (options) {
}
async function registerComponentFile (options, filePath) {
- await buildQueued(options, filePath, true)
+ await buildQueued(options, filePath, undefined, true)
const extractProperties = getExtractProperties(options)
const [properties, dependentFiles, dependencyFiles] = await Promise.all([
@@ -37,32 +36,17 @@ async function registerComponentFile (options, filePath) {
async function render (options, filePath, data = {}) {
let rendered, foot
- const { serverRenderPath, serverComponentPath, clientRenderPath, clientComponentPath } = await buildQueued(options, filePath, true)
+ const { serverResultPath, clientResultPath } = await buildQueued(options, filePath, data, true)
- if (serverRenderPath && serverComponentPath) {
- const ServerRender = require(serverRenderPath)
- const ServerComponent = require(serverComponentPath)
- const serverRender = ServerRender.default || ServerRender
- const serverComponent = ServerComponent.default || ServerComponent
- rendered = await serverRender(serverComponent, data)
+ if (serverResultPath) {
+ rendered = await requireUncached(serverResultPath)
}
- if (clientRenderPath && clientComponentPath) {
- foot = `
-
-
- `
+ if (clientResultPath) {
+ foot = ` `
}
- return {
- rendered,
- foot
- }
+ return { rendered, foot }
}
function filesForComponent (options, componentName) {
diff --git a/packages/adapter-webpack/src/util.js b/packages/adapter-webpack/src/util.js
index 808f805e..3c118d3e 100644
--- a/packages/adapter-webpack/src/util.js
+++ b/packages/adapter-webpack/src/util.js
@@ -2,6 +2,7 @@ const { join, relative } = require('path')
const hash = require('object-hash')
const webpack = require('webpack')
const merge = require('webpack-merge')
+const VirtualModulesPlugin = require('webpack-virtual-modules')
const { DebounceUtil: { debounce } } = require('@uiengine/util')
const { cacheGet, cachePut, cacheDel } = require('./cache')
@@ -56,9 +57,6 @@ const buildConfig = (options, isSetupBuild = false) => {
const entry = isSetupBuild
? { [`${ext}-client`]: clientRenderPath }
: {}
- const library = isSetupBuild
- ? 'UIengineWebpack_render'
- : 'UIengineWebpack_component'
config.client = merge(clientConfig, {
name: WEBPACK_NAME_CLIENT,
@@ -67,10 +65,7 @@ const buildConfig = (options, isSetupBuild = false) => {
entry,
output: {
path: filesDir(options),
- filename: '[name].js',
- library,
- libraryTarget: 'window',
- libraryExport: 'default'
+ filename: '[name].js'
},
plugins: [
new webpack.DefinePlugin({
@@ -83,15 +78,52 @@ const buildConfig = (options, isSetupBuild = false) => {
return config
}
-const addFileToQueue = (options, filePath, queue) => {
+const addFileToQueue = (options, filePath, data, queue) => {
if (queue.promises[filePath]) return queue.promises[filePath]
- const { serverConfig, clientConfig } = options
- const serverId = getFileId(filePath, 'server')
- const clientId = getFileId(filePath, 'client')
+ const { serverConfig, serverRenderPath, clientConfig, clientRenderPath } = options
+ const serverComponentId = getFileId(filePath, 'server-component')
+ const serverResultId = getFileId(filePath, 'server-result')
+ const clientComponentId = getFileId(filePath, 'client-component')
+ const clientResultId = getFileId(filePath, 'client-result')
+
+ if (serverConfig) {
+ queue.config.server.entry[serverComponentId] = filePath
+
+ if (data) {
+ queue.config.server.entry[serverResultId] = `/${serverResultId}.js`
+ queue.config.server.plugins.push(
+ new VirtualModulesPlugin({
+ [queue.config.server.entry[serverResultId]]: `
+ const ServerRender = require('${serverRenderPath}')
+ const ServerComponent = require('${filePath}')
+ const serverRender = ServerRender.default || ServerRender
+ const serverComponent = ServerComponent.default || ServerComponent
+
+ module.exports = serverRender(serverComponent, ${JSON.stringify(data)})
+ `
+ })
+ )
+ }
+ }
+
+ if (clientConfig) {
+ queue.config.client.entry[clientComponentId] = filePath
- if (serverConfig) queue.config.server.entry[serverId] = filePath
- if (clientConfig) queue.config.client.entry[clientId] = filePath
+ if (data) {
+ queue.config.client.entry[clientResultId] = `/${clientResultId}.js`
+ queue.config.client.plugins.push(
+ new VirtualModulesPlugin({
+ [queue.config.client.entry[clientResultId]]: `
+ import clientRender from '${clientRenderPath}'
+ import Component from '${filePath}'
+
+ export default clientRender(Component, ${JSON.stringify(data)})
+ `
+ })
+ )
+ }
+ }
// cache the promises so that files do not get added multiple times
const promise = new Promise((resolve, reject) => {
@@ -99,8 +131,10 @@ const addFileToQueue = (options, filePath, queue) => {
reject,
resolve,
filePath,
- serverId,
- clientId
+ serverComponentId,
+ serverResultId,
+ clientComponentId,
+ clientResultId
}
})
@@ -149,7 +183,7 @@ async function buildSetup (options) {
await runWebpack(config)
}
-async function buildQueued (options, filePath, clearCache = false) {
+async function buildQueued (options, filePath, data = {}, clearCache = false) {
const queueId = getQueueId(options)
if (clearCache) {
@@ -167,7 +201,7 @@ async function buildQueued (options, filePath, clearCache = false) {
}
}
- const promise = addFileToQueue(options, filePath, QUEUES[queueId])
+ const promise = addFileToQueue(options, filePath, data, QUEUES[queueId])
debounce(queueId, async () => {
const { config, handles } = QUEUES[queueId]
@@ -178,25 +212,25 @@ async function buildQueued (options, filePath, clearCache = false) {
const info = stats.toJson()
const serverInfo = info.children.find(child => child.name === WEBPACK_NAME_SERVER)
const clientInfo = info.children.find(child => child.name === WEBPACK_NAME_CLIENT)
- const { ext, uiBase } = options
-
- Object.values(handles).forEach(({ resolve, filePath, serverId, clientId }) => {
- const serverChunk = serverInfo && serverInfo.chunks.find(chunk => chunk.id === serverId)
- const clientChunk = clientInfo && clientInfo.chunks.find(chunk => chunk.id === clientId)
- const serverRenderPath = serverChunk && join(filesDir(options), `${ext}-server.js`)
- const serverComponentPath = serverChunk && join(filesDir(options), `${getFileId(filePath, 'server')}.js`)
- const clientRenderPath = clientChunk && `${uiBase}${TARGET_FOLDER}/${ext}-client.js`
- const clientComponentPath = clientChunk && `${uiBase}${TARGET_FOLDER}/${getFileId(filePath, 'client')}.js`
+ const { uiBase } = options
+
+ Object.values(handles).forEach(({ resolve, filePath, serverComponentId, clientComponentId }) => {
+ // needed for dependency resolution
+ const serverComponentChunk = serverInfo && serverInfo.chunks.find(chunk => chunk.id === serverComponentId)
+ const clientComponentChunk = clientInfo && clientInfo.chunks.find(chunk => chunk.id === clientComponentId)
+ // needed for property extraction
+ const serverComponentPath = serverComponentChunk && join(filesDir(options), `${getFileId(filePath, 'server-component')}.js`)
+ // needed for rendering
+ const serverResultPath = serverComponentChunk && join(filesDir(options), `${getFileId(filePath, 'server-result')}.js`)
+ const clientResultPath = clientComponentChunk && `${uiBase}${TARGET_FOLDER}/${getFileId(filePath, 'client-result')}.js`
- // console.log(serverId, serverChunk, serverInfo.chunks)
const object = {
filePath,
- serverChunk,
- serverRenderPath,
- serverComponentPath,
- clientChunk,
- clientRenderPath,
- clientComponentPath
+ clientComponentChunk,
+ clientResultPath,
+ serverComponentChunk,
+ serverResultPath,
+ serverComponentPath
}
cachePut(queueId, filePath, object)
diff --git a/packages/adapter-webpack/test/webpack_adapter_react_test.js b/packages/adapter-webpack/test/webpack_adapter_react_test.js
index 51538a11..fd95f047 100644
--- a/packages/adapter-webpack/test/webpack_adapter_react_test.js
+++ b/packages/adapter-webpack/test/webpack_adapter_react_test.js
@@ -4,7 +4,7 @@ const assert = require('assert')
const { join } = require('path')
const { removeSync } = require('fs-extra')
const { StringUtil: { crossPlatformPath } } = require('@uiengine/util')
-const { assertMatches, assertIncludes, assertContentMatches } = require('../../../test/support/asserts')
+const { assertMatches, assertIncludes, assertExists } = require('../../../test/support/asserts')
const { testTmpPath } = require('../../../test/support/paths')
const Adapter = require('../src/index')
@@ -67,7 +67,7 @@ describe('Webpack adapter with React templates', function () {
await Adapter.setup(options)
const clientPath = join(outputPath, 'jsx-client.js')
- assertContentMatches(clientPath, 'window["UIengineWebpack_render"]')
+ assertExists(clientPath)
const serverPath = join(outputPath, 'jsx-server.js')
const serverRender = require(serverPath)
diff --git a/packages/adapter-webpack/test/webpack_adapter_vue_test.js b/packages/adapter-webpack/test/webpack_adapter_vue_test.js
index 3568e998..c8c54d13 100644
--- a/packages/adapter-webpack/test/webpack_adapter_vue_test.js
+++ b/packages/adapter-webpack/test/webpack_adapter_vue_test.js
@@ -4,7 +4,7 @@ const assert = require('assert')
const { join } = require('path')
const { removeSync } = require('fs-extra')
const { StringUtil: { crossPlatformPath } } = require('@uiengine/util')
-const { assertMatches, assertIncludes, assertContentMatches } = require('../../../test/support/asserts')
+const { assertMatches, assertIncludes, assertExists } = require('../../../test/support/asserts')
const { testTmpPath } = require('../../../test/support/paths')
const Adapter = require('../src/index')
@@ -67,7 +67,7 @@ describe('Webpack adapter with Vue templates', function () {
await Adapter.setup(options)
const clientPath = join(outputPath, 'vue-client.js')
- assertContentMatches(clientPath, 'window["UIengineWebpack_render"]')
+ assertExists(clientPath)
const serverPath = join(outputPath, 'vue-server.js')
const serverRender = require(serverPath)
diff --git a/yarn.lock b/yarn.lock
index c2bbc3f0..629588e9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4786,7 +4786,7 @@ debug@3.1.0, debug@=3.1.0, debug@~3.1.0:
dependencies:
ms "2.0.0"
-debug@3.2.6, debug@^3.1.0, debug@^3.2.6:
+debug@3.2.6, debug@^3.0.0, debug@^3.1.0, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@@ -14491,6 +14491,13 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1:
source-list-map "^2.0.0"
source-map "~0.6.1"
+webpack-virtual-modules@^0.1.11:
+ version "0.1.11"
+ resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.1.11.tgz#8f82c74c0cc8d1ea05a0d5ed40fbe2b9b00a3ef5"
+ integrity sha512-cyaaKMkICVP333iPx+74f3azZ18qKWyvViLn0FnaU9xFki+jtdOfPlkxjQVKnSbE+0Hxz7GUEuDTU+boikWTvQ==
+ dependencies:
+ debug "^3.0.0"
+
webpack@4.39.2:
version "4.39.2"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.39.2.tgz#c9aa5c1776d7c309d1b3911764f0288c8c2816aa"