Closed maxwarch closed 8 years ago
Yes, you can use Marko with webpack. You just need to enable the markoify Browserify transform for webpack: https://github.com/raptorjs/marko#using-browserify
To use a browserify transform with webpack you can use the following webpack loader: https://github.com/webpack/transform-loader
In theory, it would probably be trivial to build a custom Marko loader for webpack, but it is not something we have plans to do. If you or someone else wants to introduce a marko-loader for webpack I'm sure that would be helpful to others.
Marko templates compile down to standard CommonJS JavaScript modules. If you pre-compile all of your templates, then the following code will always work with webpack or any other JavaScript module loader:
var template = require('marko').load(require('./template.marko.js'));
You can pre-compile your templates using the markoc
command line utility. For example:
markoc .
Pre-compilation is kind of a pain since you need to typically set up a file watching service (or Gulp/Grunt build script) compile on templates on change, but it works.
To avoid pre-compilation, we recommend the following code to load a template:
var template = require('marko').load(require.resolve('./template.marko'));
That code will work on the server-side no problem, but Browserify and WebPack do not recognize and support require.resolve
so you must use a Browserify transform to compile the Marko template automatically and transform the code to the following:
var template = require('marko').load(require('./template.marko.js'));
That's exactly what the following Browserify transform does for you: https://github.com/raptorjs/markoify
I hope that answers your question.
As a side note, you might want to consider using the optimizer since it is more feature-rich JavaScript module bundler that also supports CSS, code splitting, bundling, lazy loading, etc.
Thanks, i will try !
@maxwarch Hi! Have you succeed with webpack and marko? I'd tried it and encountered the problem that webpack 'Cannot find module 'raptor-logging-impl''. Direct installation of 'raptor-logging-impl' doesn't help. Will be nice to get your feedback. Thanks!
@KateKate hi, unfortunately i haven't the time to try this. I hope i will have !
I've not tried using marko with webpack, but I suspect that the webpack bundler is choking due to the following lines: https://github.com/raptorjs/raptor-logging/blob/b5045817e413e29077fa6fc7ac9de3243167c679/lib/raptor-logging.js#L1-L7
I'm not sure what to suggest in this case, because it seems like a bug in webpack since lasso and browserify have no issues. If anyone knows of a workaround for webpack please share.
@patrick-steele-idem thank you for your feedback.
It's a bit of a hack, but if a module uses process
and it's bundled by webpack then webpack (and browserify) sets process.browser: true
. So if the try/catches in raptor and marko's src are only there for the benefit of browserify then replacing them with if(!process.browser)
would mean the code compiles properly in webpack too @patrick-steele-idem
I've found, and found a potential workaround for, another bug in webpack.
Because, I guess, it places a higher importance on loading files with extensions other than .js
webpack tries to load mypartial.marko
rather than mypartial.marko.js
when using <include
in any template. The workaround I found is to compile <include
to e.g. __loadTemplate(require("../../components/nav/tpl.marko.js"), require)
instead of __loadTemplate(require.resolve("../../components/nav/tpl.marko"), require)
Whether this breaks anything else I don't know. If it does I'll have a go at writing a marko loader for webpack, though it wouldn't surprise me if the use of require.resolve
instead of a plain require
is still a problem
On investigating, this would involve a change to TypeConverter. Is this something you'd consider?
Hey @wheresrhys, I think the right thing to do here is to use the markoify Browserify transform with Webpack using the transform loader for webpack: https://github.com/webpack/transform-loader
The markoify
transform will auto compile the referenced Marko templates and transform the code to require the generated .marko.js
file (e.g. require('./tpl.marko.js')
. Have you given that a try?
Unfortunately, generating the following code would not work since the referenced template may not already be compiled:
__loadTemplate(require("../../components/nav/tpl.marko.js"), require)
Marko is designed to generate code that always works on the server. We use require.resolve('./template.marko')
instead of require('./template.marko')
because the Node.js require extension for Marko is optional. We provide transforms for JavaScript module bundlers so that referenced templates will automatically be compiled and required in. I hope that clarifies.
Hey @wheresrhys, were you able to get things working with with the markoify
transform? If you still think it is need to generate compiled code differently such that it doesn't use require.resolve('./foo.marko')
and instead uses require('./foo.marko')
then it might be reasonable to offer that as a compile-time option:
require('marko/compiler').defaultOptions.useRequireExtension = true;
I'm doing some housecleaning so I am going to go ahead and close this issue, but please feel free to open another Github issue if you would like to pursue the proposed idea or any other ideas. Thanks!
I tried with transform-loader and the markoify. It worked for me, but webpack does not track any changes in templates, so I just wrote no-brainer marko-loader for webpack, which solves this problem.
var marko = require('marko/compiler');
module.exports = function (source) {
if (this.cacheable) this.cacheable();
return marko.compile(source, '.', {
writeToDisk: false
});
};
@naumovs thanks for sharing. If you are interested in maintaining a loader for others to use I can give you access to github.com/marko-js/marko-loader
, or the webpack folks may let you maintain the repo at github.com/webpack/marko-loader
. It would be great to have an official webpack loader for those who want to use webpack (even if the code for the loader is trivial). It would be also good to update the marko docs to describe usage with webpack. Please let me know if you are interested in helping out.
@sergiirocks I'm using your loader but getting this error when building:
the request of a dependency is an expression
Any idea what might be happening?
Do you have an example on how to use it in webpack.config.js
?
@patrick-steele-idem I have created this test project.
https://github.com/PierBover/markojs-webpack-test
You just need to npm install
and then webpack
to reproduce the error.
Marko has been updated to be compatible with wepback. New version published: marko@3.10.1
Also see: https://github.com/marko-js/marko-loader
Awesome @patrick-steele-idem !
It does work, although I'm still getting Webpack warnings:
WARNING in ./~/marko/runtime/stream/index-browser.js Critical dependencies: 6:17-40 the request of a dependency is an expression 10:13-32 the request of a dependency is an expression @ ./~/marko/runtime/stream/index-browser.js 6:17-40 10:13-32
It does work, although I'm still getting Webpack warnings:
Yes, for now there is no way to remove the warnings without potentially breaking things. In the next version of Marko we can revisit how the optional "streams" module is enabled for the browser.
Hi, tried marko-loader - it bundles js but not css. Any suggestions?
plugins: [
// Avoid publishing files when compilation failed:
new webpack.NoEmitOnErrorsPlugin(),
// Write out CSS bundle to its own file:
new ExtractTextPlugin('dist/bundle.css', { allChunks: true })
]
test: /\.(css|less)$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader?sourceMap',
use: 'css-loader?sourceMap!less-loader'
}),
Hi, tried marko-loader - it bundles js but not css. Any suggestions?
plugins: [ // Avoid publishing files when compilation failed: new webpack.NoEmitOnErrorsPlugin(), // Write out CSS bundle to its own file: new ExtractTextPlugin('dist/bundle.css', { allChunks: true }) ]
test: /\.(css|less)$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader?sourceMap', use: 'css-loader?sourceMap!less-loader' }),
I'm also experiencing this.
Hello, is there a way to work with marko and webpack, a marko-loader perhaps ? Thanks