Hello,
recently, a pr [1] was merged that now allow to use webpack [2] power in
plugins as well - it means that now you can:
- use ES6 in your javascript code, scss/css import etc etc
- use react, or any other js library that is used by foreman core it self
in your plugin (including react components that exists in foreman core). - start extending your plugin to use advance state handling by leveraging
redux [3].
whats not complete yet, but we plan on adding (patches are welcomed :))
- support for per plugin package.json - allowing plugins add more npm
packages as they require. - support for eslint globally, we would prefer to have only one globally
defined eslintrc file and reuse it across all plugins.
the idea here is to move away from the current model we have with rubocop
where each repo needs to "catch up" with foreman, this
should allow more consistent js code base across plugins. - support for jest testing in a similar fashion to rake test.
- a script that update all dependencies - e.g. bundle update && npm update
&& plugin.each do npm update… - extend the react mounter to allow plugins to expose components.
- add storybook [4] support for plugins just like we have in core [5].
How to use it:
- make sure you have a recent foreman develop checkout (including npm
update etc) - in your view, or layout, deface etc add something like:
<%= javascript_include_tag webpack_asset_paths('your-plugin-bundle',
:extension => 'js'), "data-turbolinks-track" => true %>
- if you are uncertain on how your bundle name is called, see below for
more details.
- in your plugin, create a directory called 'webpack' (similar to foreman
core). - inside create a file called index.js and include something like:
import React from 'react';
import ReactDOM from 'react-dom';
import Icon from 'foremanReact/common/Icon';
const reactNode = document.querySelector('#some div that exists already');
if (reactNode) {
ReactDOM.render(
<Icon type='ok' />,
reactNode);
};
- execution foreman start on your foreman repo.
couple of more advance things to notice:
-
import React from 'react';
This actually pulls your dependency (in this case react) to your bundle,
however, webpack is smart enough to detect common code, and all common code
will now go to a shared bundle called vendor - e.g.Asset Size Chunks Chunk Names
bundle.js 14.2 MB 0 [emitted] [big] bundle
taskscore.js 1.8 kB 1 [emitted] taskscore
vendor.js 2.81 MB 2 [emitted] [big] vendor
bundle.css 73.7 kB 0 [emitted] bundle
manifest.json 0 bytes [emitted]
- this also shows your bundle name, in my case its taskscore - if you are
still uncertain about the bundle name, you can always simply
execute ./script/plugin_webpack_directories.rb and see the output there.
- import something from 'foremanReact/something is actually referred to
foreman code base, ForemanReact is an alias expoed by webpack that allow us
to refer to code in core.
see
https://github.com/theforeman/foreman/blob/develop/config/webpack.config.js#L45
[1] https://github.com/theforeman/foreman/pull/4625
[2] https://webpack.github.io
[3] http://redux.js.org/
[4] https://storybook.js.org/
[5] https://cdn.rawgit.com/ohadlevy/foreman/vmware-scsi/index.html