Package: calmjs.webpack
calmjs.webpackProvide the integration ofwebpackinto a Python environment through
theCalmjs frameworkto facilitate the usage of JavaScript sources
included with Python packages in conjunction with Node.js packages
sourced fromnpmor similar package repositories, for the declaration
and production of prebuilt JavaScript artifacts withwebpackin a
manner that allow reuse and extension by Python packages’ dependants.IntroductionWeb applications may be created using any language as their backends,
however interactive front-end user interfaces that they may provide
ultimately rely on some form of JavaScript.  This is especially true if
associated functionalities are sourced fromNode.jsbased package
management systems such asnpm.  However, backend languages that
offer their own package management system typically lack comprehensive
integration withnpm, or integration is tightly coupled with whatever
framework that is not reusable in a more generalized manner.A common way to address this issue is that a package may be forced to be
split into two, or at the very least a completely separate deployment
system is used, in order for the JavaScript tools to manage the front-
end facing parts.  On top of this, these separate systems do not
necessarily communicate with each other.  This results in issues such as
difficulties in building the software stack, deployments being flaky and
non-reproducible outside of the project’s context, limiting reusability
of all the components at hand as the entire process is typically tightly
coupled to the underlying source repository.  Ultimately, this leaves
the users of the backend language not able to convey front end
deployment information across package boundaries for reuse by their
dependents (e.g. for other downstream packages to extend the package in
ways that promote reusability in a way that is well-tested.)This kind of self-contained behavior also plagueswebpack, where eachNode.jspackage provide the resulting artifact, but not necessarily
the methods that went into generating them in a form that is reusable.
Sure, most typical use case for those packages can be addressed by
simply specifying the entry point, however for systems that offer
dynamic plugin-based systems this quickly becomes problematic, as
webpack requires that all imports be known at build time.  This makes
arbitrary extensions very difficult to implement without a separate
system that acts as an overseer for what modules names are available and
where they might be.As the goal of theCalmjs frameworkis to allow Python packages to
expose their JavaScript code as if they are part of thenpmmanaged
module system from the client side code, this package,calmjs.webpack,
leverages that capability to provide not only the standard invocation
method forwebpackfor Python packages, but also the ability for
downstream packages the option to generate comprehensive webpack
artifacts or standalone webpack artifacts that only contain their
specific extensions to be used in conjunction with other existing
artifacts.FeaturesHowcalmjs.webpackworksThe Calmjs framework provides the framework to allow Python packages to
declare the dependencies they need againstnpmbased packages for the
JavaScript code they provide, and also enable Python packages to expose
any JavaScript source files that they may contain in a declarative
manner.The utility included withcalmjs.webpackprovide the means to consume
those declarations, treating the JavaScript files as both source and
compilation target, with the final deployable artifact(s) being produced
throughwebpackfrom thewebpackpackage.While the input source files made available through Python packages
could be written in any format as understood by webpack, currently only
standard ES5 is properly processed.  The reason for this is thatcalmjs.parse, the parser library thatcalmjs.webpackmake use for
the parsing of JavaScript, currently only understand ES5, and is used
for extracting all the import statements to create the dynamic Calmjs
import system for webpack, and to also transpile the CommonJS and AMD (Asynchronous Module Definition)
require statements to make use of this dynamic import system.The resulting sources will be placed in a build directory, along with
all the declared bundled sources acquired from the Node.js package
managers or repositories, plus the (optionally) generated import module.
A webpack configuration file will then be generated to include all the
relevant sources as selected to enable the generation of the final
artifact file.  These can then be deployed to the appropriate
environment, or the whole above process can be included as part of the
functionality of the Python backend at hand through the API provided
through this package.Ultimately, the goal ofcalmjs.webpackis to ease the integration and
interactions between of client-side JavaScript with server-side Python,
by simplifying the task of building, shipping and deployment of the two
set of sources in one shared package and environment.  The Calmjs
framework provides the linkage between these two environment and the
tools provided by there will assist with the setup of a common,
reproducible local Node.js environments.Finally, for quality control, this package has integration withcalmjs.dev, which provides the tools needed to set up the test
environment and harnesses for running of JavaScript tests that are part
of the Python packages for the associated JavaScript code.  However,
that package is not declared as a direct dependency, as not all use
cases will require the availability of that package.  Please refer to
installation section for details.Supported webpack versionsAs webpack is a very active project, multiple major versions have been
released since the initial development and release ofcalmjs.webpack.
Currently,calmjs.webpackis known to support webpack-2 version 2.6 or
greater, webpack-3 and webpack-4.  Whilewebpack@2.7.0is declared for
this version ofcalmjs.webpack, downstream packages may declare later
versions but it is recommended that thecalmjs.webpacktest suite be
executed in full to verify that the integration tests pass for the given
version in the environment.  Detailed instructions on the execution of
the integration tests forcalmjs.webpackis covered in theTesting
the installationsection.InstallationIt is recommended that the local environment already have Node.js andnpminstalled at the very minimum to enable the installation ofwebpack, if it hasn’t already been installed and available.  Also,
the version of Python must be either 2.7 or 3.3+.  Both PyPy and PyPy3
are supported, with the recommended versions being PyPy3-5.2 or greater,
although PyPy3-2.4 should work, however there may be difficulties due to
new versions of dependencies rejecting older versions of Python.To installcalmjs.webpackinto a given Python environment, it may be
installed directly from PyPI with the following command:$pipinstallcalmjs.webpackAs this Python package interface with Node.js tools, the runtime for
this language should also be available on the system.  Please install
one of the supported LTS versions as listed on theNode.jswebsite.
Currently, the minimum supported Node.js version is 6 for this package.Installing/using webpack with calmjsTo establish a development/build environment for a Python package with
the support forwebpackthroughcalmjs.webpackin the current
working directory, the following command may be executed:$calmjsnpm--installcalmjs.webpackWhile runningnpm install webpack(along with other related packages
declared bycalmjs.webpackthat it needs fromnpm) will achieve the
same effect, do note the Calmjs framework makes it possible fornpmdependencies to be propagated down to dependent packages; such that if a
Python package that have declaredcalmjs.webpackas a dependency
(either throughinstall_requiresor anextras_requirein itssetup.py) may have its complete set of dependencies onnpmbe
installed using the following command (assuming the package is namedexample.package:$calmjsnpm--installexample.packageIf the dependency oncalmjs.webpackwas declared as an extras_require
dependency under a section namedwebpack, the command will then become
the following:$calmjsnpm--installexample.package[webpack]If the dependencies are declared correctly, using the above command will
install all the required dependencies for the JavaScript/Node.js code
required byexample.packageinto the current directory throughnpm.  Note that its dependents will also gain the declared
dependencies.For further details about how this all works can be found in the
documentation forcalmjs.  Otherwise, please continue to theusagesection.Alternative installation methods (advanced users)Development is still ongoing withcalmjs.webpack, for the latest
features and bug fixes, the development version can be installed through
git like so:$pipinstallcalmjs$pipinstallgit+https://github.com/calmjs/calmjs.webpack.git#egg=calmjs.webpackAlternatively, the git repository can be cloned directly and executepython setup.py developwhile inside the root of the source
directory.Keep in mind thatcalmjsMUST be available before thesetup.pywithin thecalmjs.webpacksource tree is executed, for it needs thepackage_jsonwriting capabilities incalmjs.  Alternatively,
please executepython setup.py egg_infoif any message aboutUnknown distribution option:is noted during the invocation ofsetup.py.Ascalmjsis declared as both namespace and package, there are certain
low-level setup that is required on the working Python environment to
ensure that all modules within can be located correctly.  However,
versions ofsetuptoolsearlier thanv31.0.0does not create the
required package namespace declarations when a package is installed
using this development installation method when mixed withpip installwithin the same namespace.  As a result, inconsistent import
failures can happen for any modules under thecalmjsnamespace.  As an
example:>>>importcalmjs.webpackTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>ImportError:Nomodulenamed'calmjs.webpack'>>>importcalmjs.base>>>importcalmjs.webpack>>>If this behavior (and workaround) is undesirable, please ensure the
installation of allcalmjsrelated packages follow the same method
(i.e. eitherpython setup.py developfor all packages, or using the
wheels acquired throughpip), or upgradesetuptoolsto version
31 or greater and reinstall all affected packages.Testing the installationFinally, to verify for the successful installation ofcalmjs.webpack,
the included tests may be executed through this command:$python-munittestcalmjs.webpack.tests.make_suiteHowever, if the steps to install external Node.js dependencies to the
current directory was followed, the current directory may be specified
as theCALMJS_TEST_ENVenvironment variable.  Under POSIX compatible
shells this may be executed instead from within that directory:$CALMJS_TEST_ENV=.python-munittestcalmjs.webpack.tests.make_suiteAs this particular form of invocation make direct use of whatever the
current Node.js environment found, this may be used to test for
compatibility with other versions of webpack intended for use with the
current environment (e.g. if a specific package declared specific later
versions of webpack for their artifact build process.).Also note that if thecalmjs.devpackage is unavailable, a number of
tests relating to integration withkarmawill be skipped.  To avoid
this, either installcalmjs.devmanually, or installcalmjs.webpackusing its extras dependencies declaration like so:$pipinstallcalmjs.webpack[dev]UsageTo generate a webpack artifact from packages that have JavaScript code
exposed through the Calmjs module registry system that are already
installed into the current environment, simply execute the following
command:$calmjswebpackexample.packageThe following sections in this document will provide an overview on how
to enable the JavaScript module export feature for a given Python
package through the Calmjs module registry system, however a more
thorough description on this topic may be found in the README provided
by thecalmjspackage, under the sectionExport JavaScript code from
Python packages.Declaring JavaScript exports for the Python packageJavaScript code embedded within a Python package can be exposed to the
Calmjs framework through thecalmjs.moduleregistry.  For example,
given the the following entry points for that registry defined by a
package namedexample:[calmjs.module]example=exampleThis is the most basic declaration that works for packages that share
the same name as the import location provided.The following is am example for packages that have nested submodules
(calledexample.libandexample.app):[calmjs.module]example.lib=example.libexample.app=example.appWhile the import locations declared looks exactly like a Python module
(as per the rules of a Python entry point), thecalmjs.moduleregistry will present them using the CommonJS/ES6 style import paths
(i.e.'example/lib'and'example/app').  Thus users that wish
to import those specific JavaScript modules will thenrequirethe
required modules prefixed by those strings.Please also note that the default source extractor will extract all
JavaScript files within those directories.  Finally, as a consequence of
how the imports are done, it is recommended that no relative imports are
to be used.If the package at hand does not directly declare its dependency oncalmjs, an explicitcalmjs_module_registry=['calmjs.module']may
need to be declared in thesetupfunction for the package to ensure
that this default module registry will be used to acquire the JavaScript
sources from.Putting this together, thesetup.pyfile should contain the
following:setup(name='example',# ... plus other declarations# this is recommendedlicense='gpl',install_requires=['calmjs>=3.0.0,<4','calmjs.webpack>=1.0.0,<2',# plus other installation requirements],# If the usage of the GPL is impossible for the project, or# declaring a direct dependency on calmjs packages is impossible# for the project for whatever other reasons (even though the# project itself will NOT be required to include/import ANY code# from the calmjs namespace), setup_requires may be used instead# of install_requires, and the following should also be included# as well:package_json={"devDependencies":{"webpack":"~2.6.0",}},calmjs_module_registry=['calmjs.module'],# the entry points are required to allow calmjs to pick this upentry_points="""
    [calmjs.module]
    example = example
    example.lib = example.lib
    example.app = example.app
    """,)For the construction of the webpack artifact for the example package, it
may be done like so through thecalmjs webpackbuild tool, which
would extract all the relevant sources, create a temporary build
directory, generate the build manifest and invokewebpackon that
file.  An example run:$calmjswebpackexampleHash:1dbcdb61e3afb4d2a383Version:webpack2.7.0Time:82msAssetSizeChunksChunkNamesexample.js4.49kB0[emitted]main[1]/tmp/tmp7qvdjb5z/build/example/lib/core.js51bytes{0}[built]cjsrequireexample/lib/core[2]/tmp/tmp7qvdjb5z/build/__calmjs_loader__.js6:24-51cjsrequireexample/lib/core[4]/tmp/tmp7qvdjb5z/build/example/app/index.js1:10-37[2]/tmp/tmp7qvdjb5z/build/__calmjs_loader__.js559bytes{0}[built]cjsrequire__calmjs_loader__[3]/tmp/tmp7qvdjb5z/build/__calmjs_bootstrap__.js3:20-48[3]/tmp/tmp7qvdjb5z/build/__calmjs_bootstrap__.js341bytes{0}[built][4]/tmp/tmp7qvdjb5z/build/example/app/index.js74bytes{0}[built]cjsrequireexample/app/index[2]/tmp/tmp7qvdjb5z/build/__calmjs_loader__.js7:25-53+1hiddenmodulesAs the build process used bycalmjs.webpackis executed in a separate
build directory, all imports through the Node.js module system must be
declared asextras_calmjs, as the availability ofnode_modules.
will not be present.  For instance, ifexample/app/index.jsrequire
the usage of thejqueryandunderscoremodules like so:var$=require('jquery'),_=require('underscore');It will need to declare the target location sourced fromnpmplus thepackage_jsonfor the dependencies, it will need to declare this in
itssetup.py:setup(# ...package_json={"dependencies":{"jquery":"~3.1.0","underscore":"~1.8.0",},"devDependencies":{# development dependencies from npm},},extras_calmjs={'node_modules':{'jquery':'jquery/dist/jquery.js','underscore':'underscore/underscore.js',},},)Once that is done, rerunpython setup.py egg_infoto write the
freshly declared metadata into the package’s egg-info directory, so that
it can be used from within the environment.calmjs npm--installexamplecan now be invoked to install thenpmdependencies into the
current directory; to permitcalmjs.webpackto find the required files
sourced fromnpmto put into the build directory forwebpackto
locate them.The resulting calmjs run may then end up looking something like this:$calmjswebpackexampleHash:fa76455e8abdb96273aaVersion:webpack2.7.0Time:332msAssetSizeChunksChunkNamesexample.js326kB0[emitted][big]main[1]/tmp/tmposbsof05/build/example/lib/core.js51bytes{0}[built]cjsrequireexample/lib/core[4]/tmp/tmposbsof05/build/__calmjs_loader__.js7:24-51cjsrequireexample/lib/core[6]/tmp/tmposbsof05/build/example/app/index.js1:10-37[2]/tmp/tmposbsof05/build/jquery.js268kB{0}[built]cjsrequirejquery[4]/tmp/tmposbsof05/build/__calmjs_loader__.js8:14-31cjsrequirejquery[6]/tmp/tmposbsof05/build/example/app/index.js2:8-25[3]/tmp/tmposbsof05/build/underscore.js52.9kB{0}[built]cjsrequireunderscore[4]/tmp/tmposbsof05/build/__calmjs_loader__.js9:18-39cjsrequireunderscore[6]/tmp/tmposbsof05/build/example/app/index.js2:31-52[4]/tmp/tmposbsof05/build/__calmjs_loader__.js633bytes{0}[built]cjsrequire__calmjs_loader__[5]/tmp/tmposbsof05/build/__calmjs_bootstrap__.js3:20-48[5]/tmp/tmposbsof05/build/__calmjs_bootstrap__.js341bytes{0}[built][6]/tmp/tmposbsof05/build/example/app/index.js128bytes{0}[built]cjsrequireexample/app/index[4]/tmp/tmposbsof05/build/__calmjs_loader__.js6:25-53+1hiddenmodulesTrigger test execution as part of webpack artifact building processFor testing, declare the appropriate entries to the module test registry
that accompanies the module registry for the given package, and with the
use of thekarmaruntime provided by thecalmjs.devpackage, the
tests may be executed as part of the webpack artifact build process.
The command is simply this:$calmjskarmawebpackexampleDo note that both thedevDependenciesprovided by bothcalmjs.devandcalmjs.webpackmust be installed.  This can
easily be done by declaring the appropriateinstall_requires, or
manually installcalmjs.devand then install the dependencies fromnpmusingcalmjs npm-D--installcalmjs.webpack[dev].Dynamic module importsWhilewebpackdoes natively support this to some extent, the support
is only implemented through direct filesystem level support.  In the
case of Calmjs, where the imports are done using identifiers on the
aliases explicitly defined in generatedwebpack.conf.jsconfiguration,webpackis unable to resolve those aliases by default.Instead of trying to makeContextReplacementPluginwork or writing
another webpack plugin, a surrogate__calmjs__import module is
automatically generated and included in each generated artifact such
that the dynamic imports will function as intended.  The rationale for
using this as a workaround is simply a desire to avoid possible API
changes towebpackas plugins of these nature will end up being
tightly coupled towebpack.With the usage of a surrogate import module, the dynamic imports also
work across multiplewebpackartifacts generated throughcalmjs webpack, however this is an advanced topic thus further documentation
will be required, as specific declaration/import order and various other
caveats exists that complicates real world usage (e.g. correct handling
of circular imports will always remain a non-trivial problem).For the simple case, imagine the following JavaScript code:varloader=function(module_name){// the dynamic importvarmodule=require(module_name);console.log(module+' was loaded dynamically.');};vardemo=loader('example/lib/core');If theexample/lib/core.jssource file was exported byexamplepackage and was included in the webpack, the above dynamic import should
function without issues at all by default without further configuration.If this dynamic import module functionality is unwanted and that no
dynamic imports are used by any JavaScript code to be included, this
feature may be disabled by the--disable-calmjs-compatflag.Handling of Webpack loadersWebpack provides the support of loaders to handle the importing of
files that are not JavaScript sources, such that the importing of files
such as text of JSON file can be done seamlessly with their import
system.  Python packages may export these resource files to make them
available for the webpack environment through a subsidiary loader
registrycalmjs.module.loaderthat will expose the relevant resource
files for namespaces defined incalmjs.moduleregistry for the given
package.As for the integration of the loaders themselves with the Calmjs
toolchain system, a separate loaderplugin registry must be specified.
For the webpack toolchain, thecalmjs.webpack.loaderpluginsregistry
is assigned as the default, which will resolve a generic handler to
handle the target resource files.  This generic handler supports the
chaining of loaders.  Specific handlers for the resource types may be
assigned directly to that registry, for example if an alternative
Node.js package is required to override the default automatically
generated handler.If this automatic resolution behavior is unwanted, a static registry is
defined atcalmjs.webpack.static.loaderpluginsfor this purpose,
however, to enable the usage of this registry at this time require the
usage of the toolchain API directly.As for specifying which resource files contained in Python packages are
to be made available for the webpack environment, the subsidiary module
loader registrycalmjs.module.loadershould be used.Putting all this together, theexamplepackage defined earlier is
now extended to expose various types of resource files for usage:[calmjs.module]example.lib=example.libexample.app=example.app[calmjs.module.loader]json=json[json]text=text[txt,json]This would make the relevant resource files under both theexample/libandexample/appnamespace available under the
relevant loaders, such that if some JavaScript code contain a require
statement like either of the following:varreadme_lib=require('text!example/lib/readme.txt');vardata_txt=require('text!example/lib/data.json');vardata=require('json!example/lib/data.json');Please do note that this will make available these full names for
dynamic module imports as the full names are exposed out of the
generated artifact.The default loaderplugin handler registry will provide the standard
handler as none are defined, such that those require statements with an
explicit loader prefix will be resolved correctly.  However, webpack has
largely deprecated the usage of explicit loader prefixes, and prefers a
syntax that imports without the prefix specified.  This requires a
different handling method, documented in the next section.Handling ofrequire()without explicitloader!prefixesIf the support of the RequireJS/AMD tooling is ignored (note that this
will affect any dependent Python packages that make use of this code
directly, as it does not currently support this import method yet), the
bare import syntax may be used, for example:varreadme_app=require('example/app/readme.txt');varstyle=require('example/app/style.css');One reason why compatibility across all toolchains, especially with
loaders, is difficult if not impossible to implement is due to the many
variations with there are a variety of methods implemented by the
different Node.js tooling.  For instance, importing stylesheets from
within webpack is usually done by chaining thestyle-loaderwith
whatever specific stylesheet loader, such ascss-loaderorsass-loaderdown the chain.  While it is possible to define the
following entry point on thecalmjs.module.loaderregistry:[calmjs.module.loader]
style!css = css[css]With the above definition, importing stylesheet resources using the
complete syntax (i.e.require('style!css!example/app/style.css');will work, but it is incompatible with therequire-cssloader as
it does not necessarily support the chaining of thestyle!loader
prefix as the RequireJS version of the plugin will apply the styles
immediately without that (this is why the loader-prefixes are considered
non-portable).So to better support this more agnostic use case,webpackprovides amodule.rulessection that dictates how the specific module is to be
loaded, so that the loaderprefix-free loading can be achieved (i.e. the
previous JavaScript fragment).  To specifically support this through
Calmjs, the resources entry points should be defined under thecalmjs.module.webpackloaderregistry instead of the commoncalmjs.module.loaderregistry.  For example:[calmjs.module]example.lib=example.libexample.app=example.app[calmjs.module.webpackloader]style-loader!css-loader=stylesheet[css]text-loader=txt[txt]Please note that while it is possible to also define the entry point
like the following:[calmjs.module.webpackloader]style!css=stylesheet[css]Previously this relies on a legacy behavior whichwebpackremoved, but
it is still supported bycalmjsandcalmjs.webpacksimply due to the
generic support of this format, but given that this registry is
specifically for webpack, there is should be no issue if the webpack
specific syntax is used, if the following caveats are addressed.Please note that if a given file name extension is defined on multiple
webpackloaders (note that the text loader has removed json as a file
name extension), the resulting behavior is undefined as the generated
configuration will not guarantee that the loaders are chained together
in the expected manner, as both loaders will be applied to the selected
files under an undefined ordering.Module names exported by thecalmjs.module.webpackloaderwill not be
made available the gathered module or import names for the dynamic
import module when processed by the default loader plugin handlers, as
there exists a number of subtle complexities that severely complicates
exposing these names in a meaningful manner for usage within the calmjs
system.  In effect, no dynamic imports will be possible after the
construction of the artifact.If a file name extension defined in this is also defined in thecalmjs.module.loaderregistry, it will also cause complications if
the dynamic import module was also generated.  This issue is related to
the issue outlined by the previous paragraph.If multiple loaders are required (such as for the case of stylesheets),
use the chained syntax as in thestyle-loader!css-loaderdefinition
to ensure that they are applied correctly, much like they would have
been if they were prefixed on the imports directly for this particular
Python package (i.e.style!css!).Much like the standardcalmjs.module.loaderregistry, the
definitions for any given filename extensions declared under thecalmjs.module.webpackloaderregistry are local to the package, so
that definitions that make use of a different set of loaders from an
upstream or downstream package will not cause interference with how they
are applied.Testing standalone, finalized webpack artifactsWebpack artifacts generated using the standardcalmjs webpacktoolchain runtime may be tested using thecalmjs karmaruntime
provided by thecalmjs.devpackage.  Given a finalizedexample.webpack.jsthat implements the features provided by theexamplepackage, the artifact may be tested with the tests provided
by theexamplepackage using the following command:$calmjskarmarun\-tcalmjs.webpack\--artifact=example.webpack.js\exampleThe above command invokes the standalone Karma runner using thecalmjs.webpacksettings to test against theexample.webpack.jsartifact file, using the tests provided by theexamplepackage.  The
test execution is similar to the one during the development process.Declaring prebuilt webpack artifacts for Python packagesFinally, to complete the Python package deployment story, the process
should include the automatic generation and inclusion of the JavaScript
artifacts in the resulting Python wheel.  This can be achieved by
specifying an entry in thecalmjs.artifactsregistry, with the key
being the filename of the artifact and the value being the import
location to a builder.  A default builder function provided atcalmjs.webpack.artifact:complete_webpackwill enable the generation
of a complete webpack artifact for the Python package.  The buildercalmjs.webpack.artifact:optimize_webpackwill do the same, but with
the optimize options enabled (currently only the minimize output is
supported).For example, a configuration that contains both forms might look like
so:[calmjs.artifacts]example.webpack.js=calmjs.webpack.artifact:complete_webpackexample.webpack.min.js=calmjs.webpack.artifact:optimize_webpackOnce those entry points are added tosetup.pyand the package
metadata is regenerated usingsetup.py egg_info, runningcalmjs artifact build example.packagewill make use of the webpack toolchain
and build the artifact atexample.webpack.jsinside thecalmjs_artifactsdirectory within the package metadata directory forexample.package.  Alternatively, for solution more integrated withsetuptools, thesetupfunction insetup.pyshould also
enable thebuild_calmjs_artifactsflag such thatsetup.py buildwill also trigger the building process.  This is useful for
automatically generating and including the artifact as part of the wheel
building process.  Consider thissetup.py:setup(name='example.package',# ... other required fields truncatedbuild_calmjs_artifacts=True,entry_points="""
    # ... other entry points truncated
    [calmjs.module]
    example.package = example.package

    [calmjs.artifacts]
    example.webpack.js = calmjs.webpack.artifact:complete_webpack
    example.webpack.min.js = calmjs.webpack.artifact:optimize_webpack
    """,)Building the wheel usingsetup.pymay result in something like this.
Note that the execution ofwebpackwas part of the process and that
the metadata (egg-info) directory was then built into the wheel.$ python setup.py bdist_wheel
running bdist_wheel
running build
...
running build_calmjs_artifacts
automatically picked registries ['calmjs.module'] for sourcepaths
using loaderplugin registry 'calmjs.webpack.loaderplugins'
using calmjs bootstrap; webpack.output.library set to '__calmjs__'
...
Version: webpack 2.7.0
Time: 240ms
             Asset    Size  Chunks                    Chunk Names
example.webpack.js   10 kB       0  [emitted]  [big]  main
...
running install_egg_info
Copying src/example.package.egg-info to build/.../wheel/example.package...
running install_scripts
creating build/.../wheel/example.package-1.0.dist-info/WHEELFor testing the package artifact, the following entry point should also
be specified under thecalmjs.artifacts.testsregistry, such that
runningcalmjs artifact karma example.packagewill execute the
JavaScript tests declared byexample.packageagainst the artifacts
that were declared incalmjs.artifacts.[calmjs.artifacts.tests]example.webpack.js=calmjs.webpack.artifact:test_complete_webpackexample.webpack.min.js=calmjs.webpack.artifact:test_complete_webpackNote that the sametest_complete_webpacktest builder will be able
to test the optimize_webpack artifact also.TroubleshootingThe following are some known issues with regards to this package and its
integration with other Python/Node.js packages.CRITICAL calmjs.runtime WebpackRuntimeError: unable to locate ‘webpack’This means the current Node.js environment is missing thewebpackpackage fromnpm; either install it manually with it or throughcalmjson this package.  If a given Python package is required to use
webpack to generate the package, itspackage_jsonshould declare
that, or declare dependency oncalmjs.webpack.CRITICAL calmjs.runtime WebpackExitError: webpack terminatedThis can be caused by a variety of reasons; it can be due to invalid
syntax in the provided JavaScript code, or that the configuration not
containing enough information forwebpackto correctly execute, or
that specificcalmjs webpackflags have been enabled in a way that
is incompatible withwebpack.  To extract further information about
the error, the samecalmjscommand may be executed once more with the--verboseand/or--debugflag enabled for extra log message
which may reveal further information about the nature of the error, or
that the full traceback may provide further information.  Detailed
information must be included for the filing of bug reports on theissue tracker.UserWarning: Unknown distribution option:During setup and installation using the development method, if this
warning message is shown, please ensure the egg metadata is correctly
generated by runningpython setup.py egg_infoin the source
directory, as the packagecalmjswas not available when the setup
script was initially executed.WARNING could not locate ‘package.json’ for the npm package ‘???-loader’The warning message is triggered when there was an attempt to use a
webpack loader without the appropriate loader module installed into the
working Node.js environment.  As a quick workaround to the webpack
artifact build issue, the missing package installation command may be
attempted, however the correct solution is for that package to declare
the correct loader package as the dependency inpackage_json.ContributeIssue Tracker:https://github.com/calmjs/calmjs.webpack/issuesSource Code:https://github.com/calmjs/calmjs.webpackLegalThecalmjs.webpackpackage is part of the calmjs project.The calmjs project is copyright (c) 2016 Auckland Bioengineering
Institute, University of Auckland.calmjs.webpackis licensed under
the terms of the GPLv2 or later.Changelog1.2.0 (2018-08-22)Various changes to enable the support of webpack 3 and 4.  [#6]Substantial modification to the generation of webpack configuration
scripts, as they are constructed through helpers that construct an
abstract syntax tree throughcalmjs.parse.  This is done so that
webpack version specific incompatibilities can be added/removed into
the generated script as executable Node.js code.A kill plugin is provided to karma by default; if webpack fails to
build, the karma process will halt, as thesingleRun: trueflag
no longer does the job for webpack.Provide the ability to interrogate artifacts that simply have their
function scope variable names mangled.  [#8]1.1.1 (2018-08-18)Ensure the line-continuation mark is filtered out in the to_identifier
helper function as the values of String node object included that mark
as ofcalmjs.parse-1.1.0.  [#7]1.1.0 (2018-07-25)Provide support of prefix-free loaders through a customized webpack
loader module registry; this one also works in tandem with thecalmjs.moduleregistry.  [#5]Integrate the support of the package resource loader registry
introduced bycalmjs-3.3.0.Bumped supportedcalmjs.devto version 2.2.0 such that the
correct test loader registries can be automatically acquired.  This
also makes it possible to declare test data files as resources for
JavaScript tests in the most straightforward manner as possibleThe base loader plugin handler will also generate a modname prefixed
with./, in an attempt to provide a more natural include mechanism
from within certain webpack loader contexts, as a number of them will
implicitly resolve by relative path for a bare import, and the goal is
to avoid further proprietary webpack syntaxes (e.g. the usage of the~prefixes to somenamespace/packageimport/inclusions done
inside the loader context).  [#4]1.0.2 (2018-05-24)Provide a builder that will generate an artifact with the supported
optimize flags enabled. [#3]1.0.1 (2018-05-03)Update the export_target production and usage of working_dir to be
inline with what is expected bycalmjs-3.1.0. [#2]1.0.0 (2018-01-12)Initial implementation of the Calmjs integration tool that enable the
production of webpack artifacts from JavaScript sources that are
included with Python packages, that also allow import of their
dependencies sourced throughnpmthrough the Calmjs framework.Enabled thecalmjs webpacktool entry point.Also provide integration withcalmjs.devby correcting the correct
hooks so that this package can be used as an advice package for the
execution of tests against artifacts generated through this package,
through the usage ofcalmjs karma webpack.Support for prebuilt artifacts for packages is provided throughcalmjs.artifactsregistry; default complete builders for both
building and testing are available via thecalmjs.webpack.artifactmodule.Webpack is pinned to ~2.6.0, as that is the current stable version
that is verified to work with building and testing of artifacts.