Skip to content
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

CWD problem serving or generating from another dir #3352

Closed
rottmann opened this issue Nov 13, 2018 · 6 comments
Closed

CWD problem serving or generating from another dir #3352

rottmann opened this issue Nov 13, 2018 · 6 comments
Assignees
Labels
question Needs help in usage

Comments

@rottmann
Copy link

Environment Info

Node version(node -v):8.12.0

Hexo and Plugin version(npm ls --depth 0): 3.7.0

For question

For our company i want to create a npm package with hexo, themes, scripts our-doc-gen, so that users can install our-doc-gen and run it with our-doc-gen server or our-doc-gen generate to view or generate the documentation.

This package has default _config.yml, scripts, etc. and you did not need to define them each time in your local project.

How is it possible to start hexo, with modules from our-doc-gen/node_modules and let it serve my-project/doc/file.md
I can't see how cwd should be configured to serve the files.

Example: our-doc-gen/bin/serve

#!/usr/bin/env node

const path = require('path')
const Hexo = require('hexo')

let cwd = path.resolve(process.cwd(), 'doc')
let output = cwd
let config = path.resolve(cwd, '_config.yml')

var hexo = new Hexo(cwd, {
  config,
  output,
  debug: 'trace'
})

hexo.init().then(function(){
// generate
//  hexo.call('generate', {}).then(function(){
//  })

// serve
  hexo.loadPlugin( path.resolve(process.cwd(), 'node_modules/hexo-server/index.js') )
    .then(function() {
      hexo.call('server', {}).then(function(){
      })
    })
})

This example serves only static files, but no .html is generated or served.

If i run generate the public dir will be created with all static files, instead of .html files. The original .md files are published and not the .html files.

local package.json

{
  "name": "our-doc-gen-test",
  "version": "1.0.0",
  "dependencies": {
    "our-doc-gen": "^1.0.0"
  },
  "hexo": {
    "version": "3.8.0"
  }
}

with all local installed dependencies the generate and serve method work, but for this you always have to install all the deps locally instead of only our-doc-gen

{
  "name": "our-doc-gen-test",
  "version": "1.0.0",
  "dependencies": {
    "handlebars-helpers": "^0.10.0",
    "hexo": "^3.7.0",
    "hexo-cli": "^1.1.0",
    "hexo-generator-archive": "^0.1.5",
    "hexo-generator-category": "^0.1.3",
    "hexo-generator-index": "^0.2.1",
    "hexo-generator-tag": "^0.2.0",
    "hexo-renderer-asciidoc": "^1.2.2",
    "hexo-renderer-ejs": "^0.3.1",
    "hexo-renderer-handlebars": "^2.0.2",
    "hexo-renderer-marked": "^0.3.2",
    "hexo-renderer-scss": "^1.2.0",
    "hexo-renderer-stylus": "^0.3.3",
    "hexo-server": "^0.3.3",
    "lunr": "^2.3.5",
    "lunr-languages": "^1.0.0",
    "momentjs": "^2.0.0"
  },
  "hexo": {
    "version": "3.8.0"
  }
}

For feature request

I think the problem is, that cwd and base_dir are the same.
A separate option input could solve this problem. Input-dir is by default cwd, if input dir has a value, the .md files should be loaded from inputdir and the plugins/modules from cwd.
Or other way around a modules-dir to specify the node_modules dir to load from.

@tcrowe
Copy link
Contributor

tcrowe commented Nov 21, 2018

Hi @rottmann 👋

It looks interesting what you're doing.

Are you able to add our-doc-gen/bin/serve to bin script to your package.json? https://docs.npmjs.com/files/package.json#bin

It should be able to execute within the context of the cwd.

@tcrowe
Copy link
Contributor

tcrowe commented Nov 21, 2018

Maybe we can put together a sample repo to demonstrate how to do this.

@rottmann
Copy link
Author

Yes added server to bin.

Currently i use a littly hacky solution which needs to patch some hexo-files manually (with package-patch in package.json - postinstall)

patch-package
--- a/node_modules/hexo/lib/box/index.js
+++ b/node_modules/hexo/lib/box/index.js
@@ -136,7 +136,9 @@ Box.prototype._checkFileStatus = function(path) {
   const ctx = this.context;
 
   return Cache.compareFile(
-    escapeBackslash(src.substring(ctx.base_dir.length)),
+escapeBackslash(src.substring(ctx.env.args.base.length)),
     () => getHash(src),
 
     () => fs.stat(src)
--- a/node_modules/hexo/lib/hexo/load_config.js
+++ b/node_modules/hexo/lib/hexo/load_config.js
@@ -34,8 +34,11 @@ module.exports = ctx => {
     config.root = config.root.replace(/\/*$/, '/');
     config.url = config.url.replace(/\/+$/, '');
 
-    ctx.public_dir = pathFn.resolve(baseDir, config.public_dir) + sep;
-    ctx.source_dir = pathFn.resolve(baseDir, config.source_dir) + sep;
+ctx.public_dir = pathFn.resolve(ctx.env.args.base || baseDir, config.public_dir) + sep;
+ctx.source_dir = pathFn.resolve(ctx.env.args.base || baseDir, config.source_dir) + sep;
     ctx.source = new Source(ctx);
 
     if (!config.theme) return;
--- a/node_modules/hexo/lib/plugins/processor/asset.js
+++ b/node_modules/hexo/lib/plugins/processor/asset.js
@@ -86,7 +86,9 @@ module.exports = ctx => {
   }
 
   function processAsset(file) {
-    const id = file.source.substring(ctx.base_dir.length).replace(/\\/g, '/');
+const id = file.source.substring(ctx.env.args.base.length).replace(/\\/g, '/');
     const Asset = ctx.model('Asset');
     const doc = Asset.findById(id);

Then i can call hexo from our-doc-gen bin in an another dir and hexo uses the templates from our-doc-gen (which is installed globally)

In /home/rottmann/test/package.json is no dependency of hexo and no hexo related module is installed locally.

Run $ our-doc-gen server in /home/rottmann/test
then hexo need this vars to serve the files:

let args = {
  base: '/home/rottmann/test', // <- this is new
  config: '/home/rottmann/test/doc/_config.yml',
  cwd: '/home/rottmann/.nvm/versions/node/v8.12.0/lib/node_modules/our-doc-gen',
  output: '/home/rottmann/test/.tmp/doc',
  _: [ 'server' ]
}
let cwd = 'doc'
hexoCli(cwd, args)

@tcrowe
Copy link
Contributor

tcrowe commented Nov 21, 2018

🤔 Hmmm this is interesting. It will take me a bit of time before I can read and understand.

If the idea is using a preconfigured hexo, like a hexo recipe, we should look into supporting that use case.

@rottmann
Copy link
Author

That's right, we create a complete package with hexo, theme, plugins, etc. but only need to install our-doc-gen to use it.
So we need only the plain doc-files with _config.yml in all our projects without configuring or installing all hexo related plugins/generators/etc.

Possible problem (with my hacky solution) could be the warehouse ID in db.json, if paths e.g. from theme has the same name as paths in doc. I did not check it in detail if full or rel paths are used. Currently i always remove the db before generate.

@stevenjoezhang
Copy link
Member

If i run generate the public dir will be created with all static files, instead of .html files. The original .md files are published and not the .html files.

According to your code

// serve
  hexo.loadPlugin( path.resolve(process.cwd(), 'node_modules/hexo-server/index.js') )
    .then(function() {
      hexo.call('server', {}).then(function(){
      })
    })
})

Since hexo-renderer-marked is not loaded, html document cannot be generated.
Hexo will look for the plugins that need to be loaded from package.json. If you don't want them to appear in package.json, you need to write some code to load the plugins one by one.

@stevenjoezhang stevenjoezhang added question Needs help in usage and removed discussion labels May 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Needs help in usage
Projects
None yet
Development

No branches or pull requests

3 participants