Warning: If you are upgrading across major versions, please read the release notes in the changelog.
I really dislike setting up build scripts. Most of the time I want to do the exact same thing:
While developing:
When ready to ship:
webpack can do most of those things pretty well out of the box. But, it sure is a pain to set it all up.
So, this is just a simplified, opinionated way to configure webpack for development and then build for production. That also supports easily generating more files.
If no one uses it but me, it will have still served its purpose.
A screencast showing how to use this module is here: http://learn.humanjavascript.com/react-ampersand/setting-up-webpack
npm install hjs-webpack
hjs-webpack relies on a number of optional dependencies to add functionality for things like CSS preprocessing, ES2015 transpiling, templates, and plugins. It doesn't make sense to specifiy all the loaders as peerDependencies since not every person will want every loader and missing peerDependencies cause commands like npm ls to error which isn't great.
So in order to get this additional functionality you should npm install the loaders and plugins you want hjs-webpack to use. If hjs-webpack detects that they are installed, then they will be used automatically without any further configuration.
Here's some more information about the available loaders and plugins and what they each do. You should install each that you want with npm install --save-dev.
Note that all of the CSS loaders and plugins require css-loader postcss-loader style-loader to be installed.
less-loader Require compiled less files. Extension: less.
stylus-loader Require compiled stylus files. Extension: styl.
sass-loader Require compiled sass files using the regular or indented syntax. Extensions: sass scss.
yeticss A plugin to add the yeticss library as a stylus plugin.
autoprefixer A plugin to auto prefix all your CSS with the necessary vendor prefixes.
babel-loader Require transpiled JS with built-in support for ES2015 and JSX. Extensions: js jsx babel.
coffee-loader Require CoffeeScript. Extension: coffee.
cjsx-loader Require CoffeeScript with support for JSX. coffee-loader must also be installed. Extension: cjsx.
awesome-typescript-loader Require TypeScript. Extension: ts.
livescript-loader Require LiveScript. Extension: ls.
url-loader Require assets that return data url if the size is less than the urlLoaderLimit. Extensions: jpg jpeg png gif svg otf eot svg ttf woff.
worker-loader This lets us more easily write code for WebWorkers. Once you npm install worker-loader you can write worker code using whatever other transpiler you're using and being able to require or import code from npm just like you would normally. If this is installed, simply name your file ending in worker.js for example main.worker.js or even just worker.js and it will be loaded as a worker and packaged up as a separate file when built. In addition, worker-loader supports inlining the code for workers and loading it as a data-uri as can be seen here: https://github.com/webpack/worker-loader/blob/master/createInlineWorker.js. To use this feature name your file SOMETHING.thread.js or just thread.js instead and it will be inlined if that feature is supported by the browser running your app (it will fallback to being loaded as a separate file otherwise).
pug-loader Require pug files as compiled functions. Extension: pug (legacy jade also supported).
visualizer-plugin A plugin to visualize and analyze your Webpack bundle to see which modules are taking up space and which might be duplicates.
npm install --save hjs-webpack
Put it at the root of your project, a typical config looks something like this:
var getConfig = require('hjs-webpack')
module.exports = getConfig({
// entry point for the app
in: 'src/app.js',
// Name or full path of output directory
// commonly named `www` or `public`. This
// is where your fully static site should
// end up for simple deployment.
out: 'public',
// This will destroy and re-create your
// `out` folder before building so you always
// get a fresh folder. Usually you want this
// but since it's destructive we make it
// false by default
clearBeforeBuild: true
})
scripts section of package.jsonI usually add something like the following scripts:
"scripts": {
"start": "hjs-dev-server",
"build": "webpack",
"deploy": "npm run build && surge -p public -d somedomain.com"
}
Assuming you've got some JS written that you've set as your in in the webpack.config.js you can run npm start and open a browser to http://localhost:3000 and you everything should Just Work™.
When you're wanting to do a build, just run npm run build. The build will generate your files into public.
Now there's a static site in public that can be deployed to something like Surge.sh, which I do by running npm run deploy.
Since we're using webpack under the hood, this is done the "webpack way".
Basically you can require your styles as if they were JavaScript files.
Simply do this in your application code:
require('./path/to/your/css/main.css')
Be sure to include the extension: .css in your require statment. If you use .styl you can write Stylus seamlessly and at the top of your stylus files you've got access to yeti.css for easy styling.
Try creating a file called main.styl containing:
@import 'yeticss'
Require it from your main application file (see in section below) and you should get some nice default styles.
Note in development mode these will be live-reloaded (hot loaded). In production, these will be extracted into their own files, including intelligent handling of referenced URLs within your stylesheets. Things like font-files and images will be extracted if they're over a certain size. You shouldn't have to worry about this too much. It should just work seamlessly.
Option #1: requiring files
Webpack lets us do var url = require('something.png') from within our app code and url is something you can safely set as the src of an image tag, for example. When you build the project, it uses the url-loader and will base64 encode and inline it if it's smaller than the urlLoaderLimit and hash and export it otherwise.
When you do this, webpack will hash the file and use that as a name. If you basically just want to require a file so webpack knows about it, the following syntax will copy the favicon to the out directory (at the root) but leave the name unchanged: require('!!file?name=favicon.ico!./real/path/to/your/favicon.ico'). The !! at the beginning will tell webpack to ignore other configured loaders so that your favicon won't get base64 encoded by the url-loader. See the webpack documentation about loader order for more info.
But, letting webpack handle images isn't always what you want to do. Sometimes you want just a simple folder of static assets and be able to reference them like you're used to. That's why there's another option:
Option #2: just put 'em in your out directory
You can also just put your assests in the out directory and tell hjs-webpack to ignore them by setting a glob pattern as the clearBeforeBuild option.
Assume an out directory called public that looks like this:
public/
some-other-generated-file.html
index.html
yourapp.1.1.1.css
yourapp.1.1.1.js
favicon.ico
images/
some-pic.png
Then, instead of setting clearBeforeBuild: true you can set it to a glob string like so: clearBeforeBuild: '!(images|favicon.ico)'.
Now when you build it'll clear everything that matches the glob pattern an nothing else.
In this case, it'd leave the images directory and your favicon.ico alone (more details in options section below).
note The development server will treat the out directory as the contentBase which means in this case the favicon would be available at /favicon.ico despite being in public.
There are 3 example projects in the /examples directory with various config setups:
The main export you get when you require('hjs-webpack') is simply a pre-configured webpack.config.js. You could take the result of that and add other plugins if you so chose, but shouldn't be necessary for most common tasks.
inThis should just be the path to the file that serves as the main entry point of your application.
outPath to directory where we're going to put generated files.
clearBeforeBuild (optional, boolean or glob string, default=false)A boolean to specify whether to clear the out folder before building.
If you wish to only clear some of this directory you can also pass a glob string. Globs are the file path matching strings you've probably seen in on the command line or in a .gitigore (i.e. **/*.js*).
The most common thing you'd probably want to do while using this module would be to exclude a directory from being cleared. The following example would clear out the public directory but leave the public/images and public/static folders intact if they exist.
getConfig({
in: 'src/app.js',
out: 'public',
clearBeforeBuild: '!(images|static)'
})
So, just to be clear, everything that matches the glob string within the out folder will be deleted when building.
isDev (optional, boolean, default=varies based on command)A boolean to indicate whether or not everything is in production mode (minified, etc.) or development mode (everything hotloaded and unminified).
By default this value is true if the command you ran contains hjs-dev-server and false otherwise. The option exists here in case you need to override the default.
devtool (optional, string, default='cheap-module-eval-source-map')A webpack developer tool to enhance debugging. See the webpack docs for more options.
uglify (optional, object)Options passed directly to the UglifyJSPlugin. Only used if isDev is false. Default:
{
compress: { warnings: false },
output: { comments: false },
sourceMap: false
}
output.filename (optional, string)This is passed directly to webpack, so you can use all the configuration options available there.
By default a filename is created for you based on the following rules:
isDev is true, then the filename is app.jsisDev is false, then the filename NAME.VERSION.js where NAME and VERSION are pulled from your package.json fileoutput.hash is true, then instead of VERSION your filename will contain the HASH of the compiled fileoutput.cssFilename (optional, string)This is passed directly to the extract-text-webpack-plugin, so you can use all the configuration options available there. Note: this is only used if isDev is true, since in development mode the css bundle is inserted dynamically into the document by the style-loader.
By default a filename is created for you based on the following rules:
isDev is true, then the filename is app.cssisDev is false, then the filename NAME.VERSION.css where NAME and `VERS$ claude mcp add hjs-webpack \
-- python -m otcore.mcp_server <graph>