-
-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extracted url-utils package from Ghost core #114
Conversation
@gargol Looking at all the ways we are using
I feel either approach, though have their own cons, resolves the ambiguity of config being passed to util method. I am generally inclined towards second as a developer because of freedom to choose utils which don't have config, but looking from Ghost's perspective, its probably better to do first where utils is used as a service which is initialized once and then used everywhere. 😄 |
Awesome feedback, thanks! 💯 agree about the 2nd approach being the best. My main concern was having to add This brings us to the 1st approach. Think it is the least intrusive approach and makes sense to have it hidden behind a constructor to have more explicit "you gotta initialize this thing before using". Will experiment with this approach 👍 |
@gargol Yeah I agree that second approach is too cumbersome for our primary usecase, and while first can still be made flexible enough like (2) with slightly more work where even if you pass empty config, it allows you to use methods which don't require config, while throwing error for ones that do. Just FYI that For (2), there is a non constructor/class as well if it suits better, where it takes advantage of JS closure to give us methods which has config initialized, without having do a proper url utils class setup. Either ways the instance returned will need to be preserved to use all around core. 😄
|
@rishabhgrg @kevinansfield pushed out changes to the initialization of the module and have extracted a few methods into separate modules (the ones that were pure functions). The rest, unfortunately, is very tied up to |
@gargol I think a nice way to extract out methods to separate file as well as being able to use global config could be what we were thinking about doing with approach (2) here. All the methods can be put in separate file(s) taking The advantage with this approach is it adds all the benefits of (2) where util methods are pure methods ready to be exported when needed in future, while taking care of its main con where config needed to be passed everywhere in ghost
as it still has advantages of (1) where it can easily be initialized at once place with config. 🤔 In module.exports = function getSubdir(config) {
// Parse local path location
var localPath = url.parse(config.url).path,
...
return subdir;
} In const getSubdir = require('./getSubdir');
...
module.exports = function deduplicateSubDir(url, config) {
var subDir = getSubdir(config),
...
return url.replace(subDirRegex, '$1' + subDir + '/');
} In const getSubdir = require('./getSubdir');
const deduplicateSubDir = require('./deduplicateSubDir');
...
utils.getSubdir = () => getSubdir(config)
utils. deduplicateSubDir = (url) => deduplicateSubDir(url, config)
... |
I tried the approach of passing the parameter to make the functions pure.
The problem with such refactoring starts when there are couple nested calls
from method to method. The main one, afair, was with 'join urls' which
operates on arguments directly :/ If I pass in a config string 'url' to it,
to pass later to getsubdir, it's impossible to distinguish without
introducing some weird convention like 'first parameter will always be a
url'. I'll check back about the details once I'm around the computer :)
…On Fri, Jun 7, 2019, 05:47 Rishabh Garg ***@***.***> wrote:
@gargol <https://github.com/gargol> I think a nice way to extract out
methods to separate file as well as being able to use global config could
be what we were thinking about doing with approach (2) here
<#114 (comment)>.
All the methods can be put in separate file(s) taking config as an extra
parameter, making them all pure methods, which allows them to be imported
in other files as well as index.js. So if getSubdir, is pure method which
takes config or url as param and returns value, in our index getSubdir we
can just wrap that method to pass it our global config, while in a method
like deduplicateSubDir we can require getSubdir pure method and pass it
config, which does not make a circular dependency.
The added advantage with this approach is it retains all the benefits of
(2) where util methods are pure methods ready to be exported when needed in
future, and also still has advantages of (1) where it can easily be
initialized at once place with config. 🤔
In getSubdir file
module.exports = function getSubdir(config) {
// Parse local path location
var localPath = url.parse(config.url).path,
subdir;
// Remove trailing slash
if (localPath !== '/') {
localPath = localPath.replace(/\/$/, '');
}
subdir = localPath === '/' ? '' : localPath;
return subdir;
}
In deduplicateSubDir file:
module.exports = function deduplicateSubDir(url, config) {
var subDir = getSubdir(config),
subDirRegex;
.....
}
In index.js -
const getSubdir = require('./getSubdir');
const deduplicateSubDir = require('./deduplicateSubDir');
...
utils.getSubdir = () => getSubdir(config)
utils. deduplicateSubDir = (url) => deduplicateSubDir(url, config)
....
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#114>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAFE4ROOYHIN7W3P4GNXXQTPZHK3XANCNFSM4HT4KQ6A>
.
|
@gargol Ah, I see what you mean! 🤔 Yeah that will mean we'll need to redefine tbh though I don't think we need to spend too much time to do this now, all of this can be done as part of cleanup later, we can just leave a comment and move on for now. Wdyt? 😄 |
Yes, leaving a note or even better opening up an issue would let us keep to
the main goal. This wasn't meant to be a full blown refactor - just an
extraction with quick possible improvements :)
Lmk if there are any other things to discuss. Would merge this in and
integrate it with the core today. Wdyt?
…On Fri, Jun 7, 2019, 07:13 Rishabh Garg ***@***.***> wrote:
@gargol <https://github.com/gargol> Ah, I see what you mean! 🤔 Yeah that
will mean we'll need to redefine joinUrl to take first parameter as config
(we can skip doing specific config and just use config as whole) and rest
as urls, probably something like joinUrl(config, ...rest). which
technically make sense in context of ghost as joinUrl should know config.
tbh though I don't think we have to do this now, all of this can be done
as part of cleanup later, we can just leave a comment and move on for now.
Wdyt? 😄
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#114>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAFE4RNIWCA7LLNPIZ5DU2TPZHU67ANCNFSM4HT4KQ6A>
.
|
@gargol Go for it 👍 |
…pendency - only tests for this specific method are now enabled
- to make initialization more obvious and follow the convention in other SDK packages Admin/Content API SDKs
1a07e01
to
c98ab69
Compare
refs TryGhost/Ghost#10773 - Extraction of common Ghost URL utils out of core based on https://github.com/TryGhost/Ghost/blob/2.23.3/core/server/services/url/utils.js utility package.
refs TryGhost/Ghost#10773 - Extraction of common Ghost URL utils out of core based on https://github.com/TryGhost/Ghost/blob/2.23.3/core/server/services/url/utils.js utility package.
refs TryGhost/Ghost#10773 - Extraction of common Ghost URL utils out of core based on https://github.com/TryGhost/Ghost/blob/2.23.3/core/server/services/url/utils.js utility package.
refs TryGhost/Ghost#10773
Adds
@tryghost/url-utils
module that is equivalent to current Ghost Url Service utils with exception to couple usage changes:init(params)
method - this allowed to decouple it from the core's config dependencyreplacePermalink
- now accepts additional parameter -timezone
which allowed to remove the dependency on Settings Cache.@rishabhgrg @kevinansfield would love to hear your opinions on these changes. Mainly wanted to double check on this additional initialization method and naming of the parameters it takes in.
To expand a bit on how initialization would work now. I'm thinking to have it initialized on server bootstrap right after the server configuration is set up. It gives one additional step but couldn't think of any nicer way of doing so.
TODO: