proscenium 0.1.1-x86_64-darwin → 0.2.0-x86_64-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/esbuild +0 -0
- data/lib/proscenium/compilers/esbuild/argument_error.js +2 -0
- data/lib/proscenium/compilers/esbuild/css_plugin.js +3 -7
- data/lib/proscenium/compilers/esbuild/resolve_plugin.js +20 -25
- data/lib/proscenium/compilers/esbuild.js +17 -5
- data/lib/proscenium/helper.rb +9 -1
- data/lib/proscenium/middleware/base.rb +4 -0
- data/lib/proscenium/middleware/esbuild.rb +11 -1
- data/lib/proscenium/middleware/outside_root.rb +26 -0
- data/lib/proscenium/middleware.rb +7 -0
- data/lib/proscenium/railtie.rb +3 -1
- data/lib/proscenium/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e3fd0fe04d0ad74e9c8a799d0f5e7a211f36754e502ae2dead2d87d84153594
|
4
|
+
data.tar.gz: 777c4b1a144554766f1397f72492182ec307c386e7ed0f1fadac5b0891a58907
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa754d0f16d6e20158b9ed6d9140f87c6212f81c3fb9a4ab6b075cf33e2ba4dcdd5e5f984eb4dc0cd2506aa1dcfdf6b89c701a9258b3932bc6abe78c63619c33
|
7
|
+
data.tar.gz: b549656184b70c8c5a0b783f39425b1213f14efe24e2e0132dd10d63ad591b843c39b233497f7ba019348992158594112f4bebfbbcdda7ef27c32730406cac87
|
data/bin/esbuild
CHANGED
Binary file
|
@@ -1,6 +1,8 @@
|
|
1
1
|
export default class ArgumentError extends Error {
|
2
2
|
static MESSAGES = {
|
3
3
|
rootRequired: 'Current working directory is required as --root.',
|
4
|
+
lightningcssBinRequired:
|
5
|
+
'Path to the lightningcss CLI binary is required as --lightningcss-bin.',
|
4
6
|
pathsRequired: 'One or more file paths or globs are required.',
|
5
7
|
|
6
8
|
rootUnknown: ({ root }) => `A valid working directory is required - received ${root}`
|
@@ -1,16 +1,12 @@
|
|
1
1
|
import { crypto } from 'std/crypto/mod.ts'
|
2
|
-
import { join,
|
2
|
+
import { join, dirname, basename } from 'std/path/mod.ts'
|
3
3
|
|
4
4
|
import { fileExists } from '../../utils.js'
|
5
5
|
import postcss from './css/postcss.js'
|
6
6
|
import setup from './setup_plugin.js'
|
7
7
|
|
8
|
-
export default setup('css', async build => {
|
8
|
+
export default setup('css', async (build, options) => {
|
9
9
|
const cwd = build.initialOptions.absWorkingDir
|
10
|
-
const lightningcssBin = resolve(
|
11
|
-
dirname(fromFileUrl(import.meta.url)),
|
12
|
-
'../../../../bin/lightningcss'
|
13
|
-
)
|
14
10
|
|
15
11
|
let customMedia
|
16
12
|
try {
|
@@ -40,7 +36,7 @@ export default setup('css', async build => {
|
|
40
36
|
}
|
41
37
|
|
42
38
|
let cmd = [
|
43
|
-
lightningcssBin,
|
39
|
+
options.lightningcssBin,
|
44
40
|
'--nesting',
|
45
41
|
'--error-recovery',
|
46
42
|
args.pluginData?.importedFromJs && '--minify',
|
@@ -11,6 +11,9 @@ export default setup('resolve', (build, options) => {
|
|
11
11
|
const runtimeCwdAlias = `${cwd}/proscenium-runtime`
|
12
12
|
let bundled = false
|
13
13
|
|
14
|
+
const env = Deno.env.get('RAILS_ENV')
|
15
|
+
const isProd = env === 'production'
|
16
|
+
|
14
17
|
return [
|
15
18
|
{
|
16
19
|
type: 'onResolve',
|
@@ -28,24 +31,7 @@ export default setup('resolve', (build, options) => {
|
|
28
31
|
return { external: true }
|
29
32
|
}
|
30
33
|
|
31
|
-
//
|
32
|
-
// if (args.path.startsWith('@proscenium/')) {
|
33
|
-
// const result = { suffix: args.suffix }
|
34
|
-
|
35
|
-
// if (args.queryParams?.has('bundle-all')) {
|
36
|
-
// bundled = true
|
37
|
-
// }
|
38
|
-
|
39
|
-
// if (bundled || args.queryParams?.has('bundle')) {
|
40
|
-
// result.path = join(runtimeDir, `${args.path.replace(/^@proscenium/, '')}/index.js`)
|
41
|
-
// } else {
|
42
|
-
// result.path = `${args.path.replace(/^@proscenium/, '/proscenium-runtime')}/index.js`
|
43
|
-
// result.external = true
|
44
|
-
// }
|
45
|
-
|
46
|
-
// return result
|
47
|
-
// }
|
48
|
-
|
34
|
+
// Rewrite the path to the actual runtime directory.
|
49
35
|
if (args.path.startsWith(runtimeCwdAlias)) {
|
50
36
|
return { path: join(runtimeDir, args.path.slice(runtimeCwdAlias.length)) }
|
51
37
|
}
|
@@ -88,11 +74,12 @@ export default setup('resolve', (build, options) => {
|
|
88
74
|
// Resolve the path using esbuild's internal resolution. This allows us to import node packages
|
89
75
|
// and extension-less paths without custom code, as esbuild with resolve them for us.
|
90
76
|
const resolveResult = await build.resolve(result.path, {
|
91
|
-
// If path is a bare module (node_modules), and resolveDir is the Proscenium runtime dir,
|
92
|
-
// use `cwd` as the `resolveDir`, otherwise pass it through
|
93
|
-
// node_modules are resolved correctly.
|
77
|
+
// If path is a bare module (node_modules), and resolveDir is the Proscenium runtime dir, or
|
78
|
+
// is the current working dir, then use `cwd` as the `resolveDir`, otherwise pass it through
|
79
|
+
// as is. This ensures that nested node_modules are resolved correctly.
|
94
80
|
resolveDir:
|
95
|
-
isBareModule(result.path) &&
|
81
|
+
isBareModule(result.path) &&
|
82
|
+
(!params.resolveDir.startsWith(cwd) || params.resolveDir.startsWith(runtimeDir))
|
96
83
|
? cwd
|
97
84
|
: params.resolveDir,
|
98
85
|
pluginData: {
|
@@ -118,9 +105,17 @@ export default setup('resolve', (build, options) => {
|
|
118
105
|
|
119
106
|
if (resolveResult.path.startsWith(runtimeDir)) {
|
120
107
|
result.path = '/proscenium-runtime' + resolveResult.path.slice(runtimeDir.length)
|
121
|
-
} else if (!resolveResult.path.startsWith(cwd)) {
|
122
|
-
//
|
123
|
-
|
108
|
+
} else if (!resolveResult.path.startsWith(cwd) && !isProd) {
|
109
|
+
// Resolved path is not in the current working directory. It could be linked to a file outside
|
110
|
+
// the CWD, or it's just invalid. If not in production, return as an outsideRoot namespaced,
|
111
|
+
// and externally suffixed path. This lets the Rails Proscenium::Middleware::OutsideRoot
|
112
|
+
// handle the import.
|
113
|
+
return {
|
114
|
+
...resolveResult,
|
115
|
+
namespace: 'outsideRoot',
|
116
|
+
path: `${resolveResult.path}?outsideRoot`,
|
117
|
+
external: true
|
118
|
+
}
|
124
119
|
} else {
|
125
120
|
result.path = resolveResult.path.slice(cwd.length)
|
126
121
|
}
|
@@ -23,7 +23,7 @@ import throwCompileError from './esbuild/compile_error.js'
|
|
23
23
|
* esbuild [OPTIONS] <PATHS_ARG>...
|
24
24
|
*
|
25
25
|
* ARGS:
|
26
|
-
* <PATHS_ARG>...
|
26
|
+
* <PATHS_ARG>... One or more file paths or globs to compile.
|
27
27
|
*
|
28
28
|
* OPTIONS:
|
29
29
|
* --root
|
@@ -31,6 +31,8 @@ import throwCompileError from './esbuild/compile_error.js'
|
|
31
31
|
* take place.
|
32
32
|
* --import-map
|
33
33
|
* Path to an import map, relative to the <root>.
|
34
|
+
* --lightningcss-bin
|
35
|
+
* Path to the lightningcss CLI binary.
|
34
36
|
* --write
|
35
37
|
* Write output to the filesystem according to esbuild logic.
|
36
38
|
* --debug
|
@@ -40,10 +42,11 @@ if (import.meta.main) {
|
|
40
42
|
!Deno.env.get('RAILS_ENV') && Deno.env.set('RAILS_ENV', 'development')
|
41
43
|
|
42
44
|
const { _: paths, ...options } = parseArgs(Deno.args, {
|
43
|
-
string: ['root', 'import-map'],
|
45
|
+
string: ['root', 'import-map', 'lightningcss-bin'],
|
44
46
|
boolean: ['write', 'debug'],
|
45
47
|
alias: {
|
46
|
-
'import-map': 'importMap'
|
48
|
+
'import-map': 'importMap',
|
49
|
+
'lightningcss-bin': 'lightningcssBin'
|
47
50
|
}
|
48
51
|
})
|
49
52
|
|
@@ -62,6 +65,7 @@ async function main(paths = [], options = {}) {
|
|
62
65
|
|
63
66
|
if (!Array.isArray(paths) || paths.length < 1) throw new ArgumentError('pathsRequired')
|
64
67
|
if (!options.root) throw new ArgumentError('rootRequired')
|
68
|
+
if (!options.lightningcssBin) throw new ArgumentError('lightningcssBinRequired')
|
65
69
|
|
66
70
|
const root = resolve(options.root)
|
67
71
|
|
@@ -76,8 +80,8 @@ async function main(paths = [], options = {}) {
|
|
76
80
|
const env = Deno.env.get('RAILS_ENV')
|
77
81
|
const isProd = env === 'production'
|
78
82
|
const isTest = env === 'test'
|
79
|
-
|
80
83
|
const entryPoints = new Set()
|
84
|
+
|
81
85
|
for (let i = 0; i < paths.length; i++) {
|
82
86
|
const path = paths[i]
|
83
87
|
|
@@ -85,6 +89,10 @@ async function main(paths = [], options = {}) {
|
|
85
89
|
for await (const file of expandGlob(path, { root })) {
|
86
90
|
file.isFile && entryPoints.add(file.path)
|
87
91
|
}
|
92
|
+
} else if (path.startsWith('/')) {
|
93
|
+
// Path is absolute, so it must be outsideRoot. Don't prefix the root.
|
94
|
+
// See Proscenium::Middleware::OutsideRoot.
|
95
|
+
entryPoints.add(path)
|
88
96
|
} else {
|
89
97
|
entryPoints.add(join(root, path))
|
90
98
|
}
|
@@ -117,7 +125,11 @@ async function main(paths = [], options = {}) {
|
|
117
125
|
jsxDev: !isTest && !isProd,
|
118
126
|
minify: isProd,
|
119
127
|
bundle: true,
|
120
|
-
plugins: [
|
128
|
+
plugins: [
|
129
|
+
envPlugin(),
|
130
|
+
resolvePlugin({ runtimeDir, importMap, debug }),
|
131
|
+
cssPlugin({ lightningcssBin: options.lightningcssBin, debug })
|
132
|
+
],
|
121
133
|
metafile: write,
|
122
134
|
write
|
123
135
|
}
|
data/lib/proscenium/helper.rb
CHANGED
@@ -3,7 +3,15 @@
|
|
3
3
|
module Proscenium
|
4
4
|
module Helper
|
5
5
|
def compute_asset_path(path, options = {})
|
6
|
-
|
6
|
+
if %i[javascript stylesheet].include?(options[:type])
|
7
|
+
result = "/#{path}"
|
8
|
+
|
9
|
+
if (qs = Proscenium.config.cache_query_string)
|
10
|
+
result << "?#{qs}"
|
11
|
+
end
|
12
|
+
|
13
|
+
return result
|
14
|
+
end
|
7
15
|
|
8
16
|
super
|
9
17
|
end
|
@@ -60,6 +60,10 @@ module Proscenium
|
|
60
60
|
response.content_type = content_type
|
61
61
|
response['X-Proscenium-Middleware'] = name
|
62
62
|
|
63
|
+
if Proscenium.config.cache_query_string
|
64
|
+
response['Cache-Control'] = "public, max-age=#{2.days.to_i}"
|
65
|
+
end
|
66
|
+
|
63
67
|
yield response if block_given?
|
64
68
|
|
65
69
|
response.finish
|
@@ -15,7 +15,9 @@ module Proscenium
|
|
15
15
|
|
16
16
|
def attempt
|
17
17
|
benchmark :esbuild do
|
18
|
-
render_response build(
|
18
|
+
render_response build(
|
19
|
+
"#{cli} --root #{root} --lightningcss-bin #{lightningcss_cli} #{path}"
|
20
|
+
)
|
19
21
|
end
|
20
22
|
rescue CompileError => e
|
21
23
|
render_response "export default #{e.detail.to_json}" do |response|
|
@@ -38,6 +40,14 @@ module Proscenium
|
|
38
40
|
Gem.bin_path 'proscenium', 'esbuild'
|
39
41
|
end
|
40
42
|
end
|
43
|
+
|
44
|
+
def lightningcss_cli
|
45
|
+
if ENV['PROSCENIUM_TEST']
|
46
|
+
'bin/lightningcss'
|
47
|
+
else
|
48
|
+
Gem.bin_path 'proscenium', 'lightningcss'
|
49
|
+
end
|
50
|
+
end
|
41
51
|
end
|
42
52
|
end
|
43
53
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Proscenium
|
4
|
+
class Middleware
|
5
|
+
# Provides a way to render files outside of the Rails root during non-production. This is
|
6
|
+
# primarily to support linked NPM modules, for example when using `pnpm link ...`.
|
7
|
+
class OutsideRoot < Esbuild
|
8
|
+
private
|
9
|
+
|
10
|
+
# @override [Esbuild] reassigns root to '/'.
|
11
|
+
def renderable?
|
12
|
+
old_root = root
|
13
|
+
@root = Pathname.new('/')
|
14
|
+
|
15
|
+
super
|
16
|
+
ensure
|
17
|
+
@root = old_root
|
18
|
+
end
|
19
|
+
|
20
|
+
# @override [Esbuild] does not remove leading slash, ensuring it is an absolute path.
|
21
|
+
def path
|
22
|
+
@request.path
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -10,6 +10,7 @@ module Proscenium
|
|
10
10
|
autoload :Base
|
11
11
|
autoload :Esbuild
|
12
12
|
autoload :Runtime
|
13
|
+
autoload :OutsideRoot
|
13
14
|
|
14
15
|
def initialize(app)
|
15
16
|
@app = app
|
@@ -38,6 +39,12 @@ module Proscenium
|
|
38
39
|
def find_type(request)
|
39
40
|
path = Pathname.new(request.path)
|
40
41
|
|
42
|
+
# Non-production only!
|
43
|
+
if request.query_string == 'outsideRoot'
|
44
|
+
return if Rails.env.production?
|
45
|
+
return OutsideRoot if path.fnmatch?(glob_types[:outsideRoot], File::FNM_EXTGLOB)
|
46
|
+
end
|
47
|
+
|
41
48
|
return Runtime if path.fnmatch?(glob_types[:runtime], File::FNM_EXTGLOB)
|
42
49
|
return Esbuild if path.fnmatch?(glob_types[:esbuild], File::FNM_EXTGLOB)
|
43
50
|
end
|
data/lib/proscenium/railtie.rb
CHANGED
@@ -13,7 +13,8 @@ module Proscenium
|
|
13
13
|
# See https://doc.deno.land/https://deno.land/std@0.145.0/path/mod.ts/~/globToRegExp
|
14
14
|
DEFAULT_GLOB_TYPES = {
|
15
15
|
esbuild: '/{config,app,lib,node_modules}/**.{js,mjs,jsx,css}',
|
16
|
-
runtime: '/proscenium-runtime/**.{js,jsx}'
|
16
|
+
runtime: '/proscenium-runtime/**.{js,jsx}',
|
17
|
+
outsideRoot: '/**/*.{js,jsx,mjs,css}'
|
17
18
|
}.freeze
|
18
19
|
|
19
20
|
class << self
|
@@ -27,6 +28,7 @@ module Proscenium
|
|
27
28
|
|
28
29
|
config.proscenium = ActiveSupport::OrderedOptions.new
|
29
30
|
config.proscenium.side_load = true
|
31
|
+
config.proscenium.cache_query_string = Rails.env.production? && ENV.fetch('REVISION', nil)
|
30
32
|
config.proscenium.auto_reload = Rails.env.development?
|
31
33
|
config.proscenium.auto_reload_paths ||= %w[lib app config]
|
32
34
|
config.proscenium.auto_reload_extensions ||= /\.(css|jsx?)$/
|
data/lib/proscenium/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proscenium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: x86_64-darwin
|
6
6
|
authors:
|
7
7
|
- Joel Moss
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actioncable
|
@@ -167,6 +167,7 @@ files:
|
|
167
167
|
- lib/proscenium/middleware/base.rb
|
168
168
|
- lib/proscenium/middleware/esbuild.rb
|
169
169
|
- lib/proscenium/middleware/lightningcss.rb
|
170
|
+
- lib/proscenium/middleware/outside_root.rb
|
170
171
|
- lib/proscenium/middleware/runtime.rb
|
171
172
|
- lib/proscenium/middleware/static.rb
|
172
173
|
- lib/proscenium/phlex.rb
|