vite-plugin-php 1.0.40 → 1.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,12 +20,14 @@ Check out the [starter repo](https://github.com/nititech/php-vite-starter) for a
20
20
 
21
21
  ## ⚡ Latest changes
22
22
 
23
- | Version | Feature |
24
- | ------- | ------------------------------------------------------------ |
25
- | 1.0.40 | Vite's "HTML Env Replacement" feature in transpiled PHP file |
26
- | 1.0.30 | Proper PHP header forwarding during development |
27
- | 1.0.20 | URL rewrite functionality to mimic mod_rewrite & friends |
28
- | 1.0.11 | Improved Windows support |
23
+ | Version | Feature |
24
+ | ------- | ------------------------------------------------------------------------------------- |
25
+ | 1.0.55 | Auto close last PHP tag if not close (usually PHP only files) |
26
+ | 1.0.50 | Using native Rollup pipeline to generate bundle -> proper error messages during build |
27
+ | 1.0.40 | Vite's "HTML Env Replacement" feature in transpiled PHP files |
28
+ | 1.0.30 | Proper PHP header forwarding during development |
29
+ | 1.0.20 | URL rewrite functionality to mimic mod_rewrite & friends |
30
+ | 1.0.11 | Improved Windows support |
29
31
 
30
32
  ## Write some PHP code in your `index.php`
31
33
 
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- const require$$0 = require('fs');
3
+ const require$$0$2 = require('fs');
4
4
  const require$$0$1 = require('path');
5
5
  const vite = require('vite');
6
- const require$$0$2 = require('tty');
6
+ const require$$0 = require('tty');
7
7
  const http = require('http');
8
8
  const child_process = require('child_process');
9
9
  const url = require('url');
@@ -15,9 +15,9 @@ const require$$0$6 = require('events');
15
15
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
16
16
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
17
17
 
18
- const require$$0__default$5 = /*#__PURE__*/_interopDefaultCompat(require$$0);
18
+ const require$$0__default$5 = /*#__PURE__*/_interopDefaultCompat(require$$0$2);
19
19
  const require$$0__default$2 = /*#__PURE__*/_interopDefaultCompat(require$$0$1);
20
- const require$$0__default = /*#__PURE__*/_interopDefaultCompat(require$$0$2);
20
+ const require$$0__default = /*#__PURE__*/_interopDefaultCompat(require$$0);
21
21
  const http__default = /*#__PURE__*/_interopDefaultCompat(http);
22
22
  const require$$0__default$1 = /*#__PURE__*/_interopDefaultCompat(require$$0$3);
23
23
  const require$$0__default$3 = /*#__PURE__*/_interopDefaultCompat(require$$0$4);
@@ -28,11 +28,6 @@ function makeID() {
28
28
  return Date.now().toString(36) + Math.random() * 100;
29
29
  }
30
30
 
31
- function writeFile(file, data) {
32
- require$$0.mkdirSync(require$$0$1.dirname(file), { recursive: true });
33
- require$$0.writeFileSync(file, data);
34
- }
35
-
36
31
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
37
32
 
38
33
  function getDefaultExportFromCjs (x) {
@@ -165,38 +160,44 @@ function initReplaceEnv(config) {
165
160
  };
166
161
  }
167
162
 
163
+ function writeFile(file, data) {
164
+ require$$0$2.mkdirSync(require$$0$1.dirname(file), { recursive: true });
165
+ require$$0$2.writeFileSync(file, data);
166
+ }
167
+
168
168
  const phpTagPattern = /<\?(?:php|).+?(\?>|$)/gis;
169
- function escapePHP({ inputFile, outputFile, config }) {
169
+ function escapePHP({ inputFile, config }) {
170
170
  const replaceEnv = initReplaceEnv(config);
171
- const input = require$$0.readFileSync(inputFile).toString();
172
- const codeTokens = {};
171
+ const input = require$$0$2.readFileSync(inputFile, "utf-8").toString();
172
+ const phpCodes = {};
173
173
  const isJS = inputFile.includes(".js") || inputFile.includes(".ts");
174
174
  const isML = inputFile.includes(".php") || inputFile.includes(".htm");
175
- const out = input.replace(phpTagPattern, (match) => {
175
+ const escapedCode = input.replace(phpTagPattern, (match) => {
176
176
  let token = makeID();
177
177
  if (isJS) {
178
178
  token = `/*${token}*/`;
179
179
  } else if (isML) {
180
180
  token = `<!--${token}-->`;
181
181
  }
182
- codeTokens[token] = replaceEnv(match, inputFile);
182
+ phpCodes[token] = replaceEnv(match, inputFile);
183
183
  return token;
184
184
  });
185
- writeFile(outputFile + ".json", JSON.stringify(codeTokens));
186
- writeFile(outputFile, out);
187
- }
188
- function unescapePHP({ file, tokensFile }) {
189
- const input = require$$0.readFileSync(file).toString();
190
- let out = input;
191
- const tknsFile = tokensFile || file + ".json";
192
- if (require$$0.existsSync(tknsFile)) {
193
- const codeTokens = JSON.parse(require$$0.readFileSync(tknsFile).toString());
194
- Object.entries(codeTokens).forEach(([token, code]) => {
195
- out = out.replace(token, (match) => {
196
- return `${code}`;
197
- });
185
+ return {
186
+ escapedCode,
187
+ phpCodes,
188
+ write(outputFile) {
189
+ writeFile(outputFile, escapedCode);
190
+ writeFile(outputFile + ".json", JSON.stringify(phpCodes));
191
+ }
192
+ };
193
+ }
194
+ function unescapePHP({ escapedCode, phpCodes }) {
195
+ let out = escapedCode;
196
+ Object.entries(phpCodes).forEach(([token, code]) => {
197
+ out = out.replace(token, (match) => {
198
+ return `${code}`;
198
199
  });
199
- }
200
+ });
200
201
  return out;
201
202
  }
202
203
 
@@ -6956,6 +6957,22 @@ var out = FastGlob;
6956
6957
 
6957
6958
  const fastGlob = /*@__PURE__*/getDefaultExportFromCjs(out);
6958
6959
 
6960
+ function consoleHijack(entries) {
6961
+ ["log", "info", "warn", "error"].forEach((command) => {
6962
+ const cx = console[command];
6963
+ console[command] = function(...args) {
6964
+ cx.apply(
6965
+ this,
6966
+ args.map(
6967
+ (arg) => typeof arg === "string" ? entries.reduce((acc, entry) => {
6968
+ return acc.replace(entry + ".html", entry);
6969
+ }, arg) : arg
6970
+ )
6971
+ );
6972
+ };
6973
+ });
6974
+ }
6975
+
6959
6976
  const internalParam = "__314159265359__";
6960
6977
  function usePHP(cfg = {}) {
6961
6978
  const {
@@ -6973,9 +6990,8 @@ function usePHP(cfg = {}) {
6973
6990
  function getTempFileName(file) {
6974
6991
  return `${tempDir}/${file}.html`;
6975
6992
  }
6976
- function cleanupTemp(dir = "") {
6977
- const parentDir = dir ? dir + "/" : dir;
6978
- require$$0.rmSync(parentDir + tempDir, { recursive: true, force: true });
6993
+ function cleanupTemp() {
6994
+ require$$0$2.rmSync(tempDir, { recursive: true, force: true });
6979
6995
  }
6980
6996
  function onExit() {
6981
6997
  if (config?.command === "serve") {
@@ -7000,40 +7016,50 @@ function usePHP(cfg = {}) {
7000
7016
  enforce: "post",
7001
7017
  config(config2, env) {
7002
7018
  const gitIgnoreFile = `${tempDir}/.gitignore`;
7003
- if (!require$$0.existsSync(gitIgnoreFile)) {
7019
+ if (!require$$0$2.existsSync(gitIgnoreFile)) {
7004
7020
  writeFile(gitIgnoreFile, "*\n**/*.php.html");
7005
7021
  }
7006
- entries = entries.flatMap(
7007
- (entry2) => fastGlob.globSync(entry2, {
7008
- dot: true,
7009
- onlyFiles: true,
7010
- unique: true,
7011
- ignore: [tempDir, config2.build?.outDir || "dist"]
7012
- })
7013
- );
7014
- const inputs = entries.map(getTempFileName);
7022
+ entries = [
7023
+ ...new Set(
7024
+ entries.flatMap(
7025
+ (entry2) => fastGlob.globSync(entry2, {
7026
+ dot: true,
7027
+ onlyFiles: true,
7028
+ unique: true,
7029
+ ignore: [
7030
+ tempDir,
7031
+ config2.build?.outDir || "dist"
7032
+ ]
7033
+ })
7034
+ )
7035
+ )
7036
+ ];
7037
+ consoleHijack(entries);
7015
7038
  return {
7016
7039
  build: {
7017
- rollupOptions: { input: inputs }
7040
+ rollupOptions: { input: entries }
7018
7041
  },
7019
- optimizeDeps: { entries: inputs }
7042
+ optimizeDeps: { entries }
7020
7043
  };
7021
7044
  },
7022
7045
  configResolved(_config) {
7023
7046
  config = _config;
7024
- entries.forEach(
7025
- (entry2) => escapePHP({
7026
- inputFile: entry2,
7027
- outputFile: getTempFileName(entry2),
7028
- config
7029
- })
7030
- );
7031
7047
  }
7032
7048
  },
7033
7049
  {
7034
7050
  name: "serve-php",
7035
7051
  apply: "serve",
7036
7052
  enforce: "pre",
7053
+ configResolved(_config) {
7054
+ config = _config;
7055
+ entries.forEach((entry2) => {
7056
+ const outputFile = getTempFileName(entry2);
7057
+ escapePHP({
7058
+ inputFile: entry2,
7059
+ config
7060
+ }).write(outputFile);
7061
+ });
7062
+ },
7037
7063
  configureServer(server) {
7038
7064
  viteServer = server;
7039
7065
  phpServer.start(viteServer?.config.root);
@@ -7062,7 +7088,7 @@ function usePHP(cfg = {}) {
7062
7088
  });
7063
7089
  if (entry2) {
7064
7090
  const tempFile = getTempFileName(entry2);
7065
- if (require$$0.existsSync(require$$0$1.resolve(tempFile))) {
7091
+ if (require$$0$2.existsSync(require$$0$1.resolve(tempFile))) {
7066
7092
  url.pathname = tempFile;
7067
7093
  url.port = phpServer.port.toString();
7068
7094
  url.searchParams.set(
@@ -7119,14 +7145,14 @@ function usePHP(cfg = {}) {
7119
7145
  },
7120
7146
  handleHotUpdate({ server, file }) {
7121
7147
  const entry2 = entries.find(
7122
- (entryFile) => file.endsWith(entryFile) && require$$0$1.resolve(entryFile) === file
7148
+ (entryFile) => require$$0$1.resolve(entryFile) === file
7123
7149
  );
7124
7150
  if (entry2) {
7151
+ const outputFile = getTempFileName(entry2);
7125
7152
  escapePHP({
7126
7153
  inputFile: entry2,
7127
- outputFile: getTempFileName(entry2),
7128
7154
  config
7129
- });
7155
+ }).write(outputFile);
7130
7156
  server.ws.send({
7131
7157
  type: "full-reload",
7132
7158
  path: "*"
@@ -7137,22 +7163,49 @@ function usePHP(cfg = {}) {
7137
7163
  {
7138
7164
  name: "build-php",
7139
7165
  apply: "build",
7166
+ enforce: "pre",
7140
7167
  resolveId(source, importer, options) {
7141
- if (importer?.endsWith(".html") && importer.includes(`/${tempDir}/`)) {
7142
- return { id: require$$0$1.resolve(source) };
7168
+ if (entries.includes(source)) {
7169
+ return {
7170
+ id: `${source}.html`,
7171
+ resolvedBy: "vite-plugin-php",
7172
+ meta: {
7173
+ originalId: source
7174
+ }
7175
+ };
7143
7176
  }
7144
7177
  },
7145
- closeBundle() {
7146
- const distDir = config?.build.outDir;
7147
- entries.forEach((file) => {
7148
- const tempFileName = getTempFileName(file);
7149
- const code = unescapePHP({
7150
- file: `${distDir}/${tempFileName}`,
7151
- tokensFile: `${tempFileName}.json`
7178
+ load(id, options) {
7179
+ const entry2 = this.getModuleInfo(id)?.meta.originalId;
7180
+ if (entry2) {
7181
+ const { escapedCode, phpCodes } = escapePHP({
7182
+ inputFile: entry2,
7183
+ config
7152
7184
  });
7153
- writeFile(`${distDir}/${file}`, code);
7154
- });
7155
- cleanupTemp(distDir);
7185
+ return {
7186
+ code: escapedCode,
7187
+ meta: { phpCodes }
7188
+ };
7189
+ }
7190
+ },
7191
+ generateBundle: {
7192
+ order: "post",
7193
+ handler(options, bundle, isWrite) {
7194
+ Object.entries(bundle).forEach(([key, item]) => {
7195
+ if (item.type === "asset") {
7196
+ const meta = this.getModuleInfo(
7197
+ item.fileName
7198
+ )?.meta;
7199
+ if (meta?.originalId && meta?.phpCodes) {
7200
+ item.fileName = meta.originalId;
7201
+ item.source = unescapePHP({
7202
+ escapedCode: item.source.toString(),
7203
+ phpCodes: meta.phpCodes
7204
+ });
7205
+ }
7206
+ }
7207
+ });
7208
+ }
7156
7209
  }
7157
7210
  }
7158
7211
  ];
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import require$$0$5, { mkdirSync, writeFileSync, readFileSync, existsSync, rmSync } from 'fs';
2
- import require$$0$2, { dirname, relative, resolve } from 'path';
2
+ import require$$0$2, { relative, dirname, resolve } from 'path';
3
3
  import { normalizePath } from 'vite';
4
4
  import require$$0 from 'tty';
5
5
  import http from 'http';
@@ -14,11 +14,6 @@ function makeID() {
14
14
  return Date.now().toString(36) + Math.random() * 100;
15
15
  }
16
16
 
17
- function writeFile(file, data) {
18
- mkdirSync(dirname(file), { recursive: true });
19
- writeFileSync(file, data);
20
- }
21
-
22
17
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
23
18
 
24
19
  function getDefaultExportFromCjs (x) {
@@ -151,38 +146,44 @@ function initReplaceEnv(config) {
151
146
  };
152
147
  }
153
148
 
149
+ function writeFile(file, data) {
150
+ mkdirSync(dirname(file), { recursive: true });
151
+ writeFileSync(file, data);
152
+ }
153
+
154
154
  const phpTagPattern = /<\?(?:php|).+?(\?>|$)/gis;
155
- function escapePHP({ inputFile, outputFile, config }) {
155
+ function escapePHP({ inputFile, config }) {
156
156
  const replaceEnv = initReplaceEnv(config);
157
- const input = readFileSync(inputFile).toString();
158
- const codeTokens = {};
157
+ const input = readFileSync(inputFile, "utf-8").toString();
158
+ const phpCodes = {};
159
159
  const isJS = inputFile.includes(".js") || inputFile.includes(".ts");
160
160
  const isML = inputFile.includes(".php") || inputFile.includes(".htm");
161
- const out = input.replace(phpTagPattern, (match) => {
161
+ const escapedCode = input.replace(phpTagPattern, (match) => {
162
162
  let token = makeID();
163
163
  if (isJS) {
164
164
  token = `/*${token}*/`;
165
165
  } else if (isML) {
166
166
  token = `<!--${token}-->`;
167
167
  }
168
- codeTokens[token] = replaceEnv(match, inputFile);
168
+ phpCodes[token] = replaceEnv(match, inputFile);
169
169
  return token;
170
170
  });
171
- writeFile(outputFile + ".json", JSON.stringify(codeTokens));
172
- writeFile(outputFile, out);
173
- }
174
- function unescapePHP({ file, tokensFile }) {
175
- const input = readFileSync(file).toString();
176
- let out = input;
177
- const tknsFile = tokensFile || file + ".json";
178
- if (existsSync(tknsFile)) {
179
- const codeTokens = JSON.parse(readFileSync(tknsFile).toString());
180
- Object.entries(codeTokens).forEach(([token, code]) => {
181
- out = out.replace(token, (match) => {
182
- return `${code}`;
183
- });
171
+ return {
172
+ escapedCode,
173
+ phpCodes,
174
+ write(outputFile) {
175
+ writeFile(outputFile, escapedCode);
176
+ writeFile(outputFile + ".json", JSON.stringify(phpCodes));
177
+ }
178
+ };
179
+ }
180
+ function unescapePHP({ escapedCode, phpCodes }) {
181
+ let out = escapedCode;
182
+ Object.entries(phpCodes).forEach(([token, code]) => {
183
+ out = out.replace(token, (match) => {
184
+ return `${code}`;
184
185
  });
185
- }
186
+ });
186
187
  return out;
187
188
  }
188
189
 
@@ -6942,6 +6943,22 @@ var out = FastGlob;
6942
6943
 
6943
6944
  const fastGlob = /*@__PURE__*/getDefaultExportFromCjs(out);
6944
6945
 
6946
+ function consoleHijack(entries) {
6947
+ ["log", "info", "warn", "error"].forEach((command) => {
6948
+ const cx = console[command];
6949
+ console[command] = function(...args) {
6950
+ cx.apply(
6951
+ this,
6952
+ args.map(
6953
+ (arg) => typeof arg === "string" ? entries.reduce((acc, entry) => {
6954
+ return acc.replace(entry + ".html", entry);
6955
+ }, arg) : arg
6956
+ )
6957
+ );
6958
+ };
6959
+ });
6960
+ }
6961
+
6945
6962
  const internalParam = "__314159265359__";
6946
6963
  function usePHP(cfg = {}) {
6947
6964
  const {
@@ -6959,9 +6976,8 @@ function usePHP(cfg = {}) {
6959
6976
  function getTempFileName(file) {
6960
6977
  return `${tempDir}/${file}.html`;
6961
6978
  }
6962
- function cleanupTemp(dir = "") {
6963
- const parentDir = dir ? dir + "/" : dir;
6964
- rmSync(parentDir + tempDir, { recursive: true, force: true });
6979
+ function cleanupTemp() {
6980
+ rmSync(tempDir, { recursive: true, force: true });
6965
6981
  }
6966
6982
  function onExit() {
6967
6983
  if (config?.command === "serve") {
@@ -6989,37 +7005,47 @@ function usePHP(cfg = {}) {
6989
7005
  if (!existsSync(gitIgnoreFile)) {
6990
7006
  writeFile(gitIgnoreFile, "*\n**/*.php.html");
6991
7007
  }
6992
- entries = entries.flatMap(
6993
- (entry2) => fastGlob.globSync(entry2, {
6994
- dot: true,
6995
- onlyFiles: true,
6996
- unique: true,
6997
- ignore: [tempDir, config2.build?.outDir || "dist"]
6998
- })
6999
- );
7000
- const inputs = entries.map(getTempFileName);
7008
+ entries = [
7009
+ ...new Set(
7010
+ entries.flatMap(
7011
+ (entry2) => fastGlob.globSync(entry2, {
7012
+ dot: true,
7013
+ onlyFiles: true,
7014
+ unique: true,
7015
+ ignore: [
7016
+ tempDir,
7017
+ config2.build?.outDir || "dist"
7018
+ ]
7019
+ })
7020
+ )
7021
+ )
7022
+ ];
7023
+ consoleHijack(entries);
7001
7024
  return {
7002
7025
  build: {
7003
- rollupOptions: { input: inputs }
7026
+ rollupOptions: { input: entries }
7004
7027
  },
7005
- optimizeDeps: { entries: inputs }
7028
+ optimizeDeps: { entries }
7006
7029
  };
7007
7030
  },
7008
7031
  configResolved(_config) {
7009
7032
  config = _config;
7010
- entries.forEach(
7011
- (entry2) => escapePHP({
7012
- inputFile: entry2,
7013
- outputFile: getTempFileName(entry2),
7014
- config
7015
- })
7016
- );
7017
7033
  }
7018
7034
  },
7019
7035
  {
7020
7036
  name: "serve-php",
7021
7037
  apply: "serve",
7022
7038
  enforce: "pre",
7039
+ configResolved(_config) {
7040
+ config = _config;
7041
+ entries.forEach((entry2) => {
7042
+ const outputFile = getTempFileName(entry2);
7043
+ escapePHP({
7044
+ inputFile: entry2,
7045
+ config
7046
+ }).write(outputFile);
7047
+ });
7048
+ },
7023
7049
  configureServer(server) {
7024
7050
  viteServer = server;
7025
7051
  phpServer.start(viteServer?.config.root);
@@ -7105,14 +7131,14 @@ function usePHP(cfg = {}) {
7105
7131
  },
7106
7132
  handleHotUpdate({ server, file }) {
7107
7133
  const entry2 = entries.find(
7108
- (entryFile) => file.endsWith(entryFile) && resolve(entryFile) === file
7134
+ (entryFile) => resolve(entryFile) === file
7109
7135
  );
7110
7136
  if (entry2) {
7137
+ const outputFile = getTempFileName(entry2);
7111
7138
  escapePHP({
7112
7139
  inputFile: entry2,
7113
- outputFile: getTempFileName(entry2),
7114
7140
  config
7115
- });
7141
+ }).write(outputFile);
7116
7142
  server.ws.send({
7117
7143
  type: "full-reload",
7118
7144
  path: "*"
@@ -7123,22 +7149,49 @@ function usePHP(cfg = {}) {
7123
7149
  {
7124
7150
  name: "build-php",
7125
7151
  apply: "build",
7152
+ enforce: "pre",
7126
7153
  resolveId(source, importer, options) {
7127
- if (importer?.endsWith(".html") && importer.includes(`/${tempDir}/`)) {
7128
- return { id: resolve(source) };
7154
+ if (entries.includes(source)) {
7155
+ return {
7156
+ id: `${source}.html`,
7157
+ resolvedBy: "vite-plugin-php",
7158
+ meta: {
7159
+ originalId: source
7160
+ }
7161
+ };
7129
7162
  }
7130
7163
  },
7131
- closeBundle() {
7132
- const distDir = config?.build.outDir;
7133
- entries.forEach((file) => {
7134
- const tempFileName = getTempFileName(file);
7135
- const code = unescapePHP({
7136
- file: `${distDir}/${tempFileName}`,
7137
- tokensFile: `${tempFileName}.json`
7164
+ load(id, options) {
7165
+ const entry2 = this.getModuleInfo(id)?.meta.originalId;
7166
+ if (entry2) {
7167
+ const { escapedCode, phpCodes } = escapePHP({
7168
+ inputFile: entry2,
7169
+ config
7138
7170
  });
7139
- writeFile(`${distDir}/${file}`, code);
7140
- });
7141
- cleanupTemp(distDir);
7171
+ return {
7172
+ code: escapedCode,
7173
+ meta: { phpCodes }
7174
+ };
7175
+ }
7176
+ },
7177
+ generateBundle: {
7178
+ order: "post",
7179
+ handler(options, bundle, isWrite) {
7180
+ Object.entries(bundle).forEach(([key, item]) => {
7181
+ if (item.type === "asset") {
7182
+ const meta = this.getModuleInfo(
7183
+ item.fileName
7184
+ )?.meta;
7185
+ if (meta?.originalId && meta?.phpCodes) {
7186
+ item.fileName = meta.originalId;
7187
+ item.source = unescapePHP({
7188
+ escapedCode: item.source.toString(),
7189
+ phpCodes: meta.phpCodes
7190
+ });
7191
+ }
7192
+ }
7193
+ });
7194
+ }
7142
7195
  }
7143
7196
  }
7144
7197
  ];
package/dist/router.php CHANGED
@@ -14,13 +14,23 @@ $_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME'
14
14
  $_SERVER['QUERY_STRING'] = http_build_query($_GET);
15
15
 
16
16
  $source = file_get_contents($sourceFile);
17
- $codeTokens = json_decode(file_get_contents("$sourceFile.json"), true);
18
17
 
19
- $source = str_replace(
20
- array_keys($codeTokens),
21
- array_values($codeTokens),
22
- $source,
23
- );
18
+ $tokensFile = "$sourceFile.json";
19
+ if (file_exists($tokensFile)) {
20
+ $codeTokens = json_decode(file_get_contents($tokensFile), true);
21
+
22
+ $source = str_replace(
23
+ array_keys($codeTokens),
24
+ array_values($codeTokens),
25
+ $source,
26
+ );
27
+ }
28
+
29
+ preg_match('#<\?((?!\?>).)*$#s', $source, $matches);
30
+
31
+ if (count($matches)) {
32
+ $source .= ' ?>';
33
+ }
24
34
 
25
35
  (function () {
26
36
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-php",
3
- "version": "1.0.40",
3
+ "version": "1.0.55",
4
4
  "description": "Process PHP-files with the speed and tools of Vite",
5
5
  "keywords": [
6
6
  "vite",