2015-12-19 14:52:17 +01:00
|
|
|
title: Webpack
|
|
|
|
---
|
2015-12-26 15:11:45 +01:00
|
|
|
summary: Shows how to use webpack to do Sass, Less or other things with Lektor.
|
2015-12-19 14:52:17 +01:00
|
|
|
---
|
|
|
|
body:
|
|
|
|
|
|
|
|
Websites are exploding in complexity and even static websites are no exception
|
|
|
|
to this. In particular systems like bootstrap and friends no longer just come
|
|
|
|
in CSS files but they come with their own build setup to ship JavaScript files,
|
|
|
|
they use Less or Sass to build the stylesheets and much more.
|
|
|
|
|
|
|
|
Right now there is a fight between different systems to figure out which way
|
|
|
|
the journey will go, but one of the best solutions has turned out to be
|
|
|
|
[webpack :ext](https://webpack.github.io/).
|
|
|
|
|
|
|
|
Webpack is not natively supported by Lektor but there is an official [Webpack
|
|
|
|
Support Plugin :ext](https://github.com/lektor/lektor-webpack-support) which
|
|
|
|
can be used to make Lektor and Webpack friends.
|
|
|
|
|
|
|
|
## Enabling the Plugin
|
|
|
|
|
|
|
|
First you need to enable the plugin. The following command will do that
|
|
|
|
for you:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ lektor plugins add webpack-support
|
|
|
|
```
|
|
|
|
|
|
|
|
## Webpack Setup
|
|
|
|
|
|
|
|
Now you need to configure webpack. The plugin expects a webpack project in the
|
|
|
|
`webpack/` folder. Within you will need a `package.json` as well as a
|
|
|
|
`webpack.config.js`
|
|
|
|
|
|
|
|
### `package.json`
|
|
|
|
|
2017-02-21 23:14:31 +01:00
|
|
|
This file instructs `npm` which packages we will need.
|
2015-12-19 14:52:17 +01:00
|
|
|
|
2017-02-21 23:14:31 +01:00
|
|
|
[npm-init :ext](https://docs.npmjs.com/cli/init) is a command-line tool to
|
|
|
|
interactively create a ``package.json`` file.
|
|
|
|
|
|
|
|
```
|
|
|
|
$ npm init
|
|
|
|
```
|
|
|
|
|
|
|
|
This will ask you a bunch of questions (invoke with ``--yes`` to use default
|
2017-02-21 23:38:43 +01:00
|
|
|
values) and then generate a ``package.json`` file for you.
|
|
|
|
|
|
|
|
It should look similar to the following example. Please **do not** just
|
|
|
|
copy-paste this! Instead run the tool, so that your ``package.json`` meets
|
|
|
|
the latest format specification.
|
2016-12-09 16:24:10 +01:00
|
|
|
|
2015-12-19 14:52:17 +01:00
|
|
|
```json
|
|
|
|
{
|
2017-02-21 23:14:31 +01:00
|
|
|
"name": "lektor-example",
|
2016-12-09 16:24:10 +01:00
|
|
|
"version": "0.1.0",
|
2017-02-21 23:14:31 +01:00
|
|
|
"description": "",
|
|
|
|
"main": "index.js",
|
|
|
|
"scripts": {
|
|
|
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
|
|
},
|
|
|
|
"author": "",
|
|
|
|
"license": "MIT"
|
2015-12-19 14:52:17 +01:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2015-12-26 15:11:45 +01:00
|
|
|
Now we can `npm install` all the things we want:
|
2015-12-19 14:52:17 +01:00
|
|
|
|
|
|
|
```
|
2015-12-27 15:08:48 +01:00
|
|
|
$ npm install --save-dev webpack babel-core node-sass babel-loader sass-loader css-loader url-loader style-loader file-loader extract-text-webpack-plugin
|
2015-12-19 14:52:17 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
This will install webpack itself together with babel and sass as well as
|
|
|
|
a bunch of loaders we need for getting all that configured. Because we
|
2015-12-26 15:11:45 +01:00
|
|
|
created a `package.json` before and we used `--save-dev` the dependencies
|
2015-12-19 14:52:17 +01:00
|
|
|
will be remembered in the `package.json` file.
|
|
|
|
|
|
|
|
### `webpack.config.js`
|
|
|
|
|
|
|
|
Next up is the webpack config file. Here we will go with a very basic
|
|
|
|
setup that's good enough to cover most things you will encounter. The
|
|
|
|
idea is to build the files from `webpack/scss` and `webpack/js` into
|
|
|
|
`assets/static/gen` so that we can use it even if we do not have webpack
|
|
|
|
installed for as long as someone else ran it before.
|
|
|
|
|
|
|
|
In this example we will configure the following things:
|
|
|
|
|
|
|
|
* all `.scss` files will be processed with Sass
|
|
|
|
* all `.js` files will be processed with Babel to convert ES6 into ES5
|
|
|
|
* JS and CSS files will be minified
|
|
|
|
* all built files will go to `assets/static/gen`
|
|
|
|
* there will be a `gen/app.js` and a `gen/styles.css` file to include
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
var webpack = require('webpack');
|
|
|
|
var path = require('path');
|
|
|
|
var ExtractTextPlugin = require('extract-text-webpack-plugin');
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
entry: {
|
2015-12-27 15:08:48 +01:00
|
|
|
'app': './js/main.js',
|
|
|
|
'styles': './scss/main.scss'
|
2015-12-19 14:52:17 +01:00
|
|
|
},
|
|
|
|
output: {
|
|
|
|
path: path.dirname(__dirname) + '/assets/static/gen',
|
|
|
|
filename: '[name].js'
|
|
|
|
},
|
|
|
|
devtool: '#cheap-module-source-map',
|
|
|
|
resolve: {
|
2017-06-14 19:55:04 +02:00
|
|
|
modules: ['node_modules'],
|
|
|
|
extensions: ['.js']
|
2015-12-19 14:52:17 +01:00
|
|
|
},
|
|
|
|
module: {
|
2017-06-14 19:55:04 +02:00
|
|
|
rules: [
|
2015-12-19 14:52:17 +01:00
|
|
|
{ test: /\.js$/, exclude: /node_modules/,
|
|
|
|
loader: 'babel-loader' },
|
|
|
|
{ test: /\.scss$/,
|
2017-06-14 19:55:04 +02:00
|
|
|
loader: ExtractTextPlugin.extract({
|
|
|
|
fallback: 'style-loader',
|
|
|
|
use: 'css-loader!sass-loader' } ) },
|
2015-12-19 14:52:17 +01:00
|
|
|
{ test: /\.css$/,
|
2017-06-14 19:55:04 +02:00
|
|
|
loader: ExtractTextPlugin.extract({
|
|
|
|
fallback: 'style-loader',
|
|
|
|
use: 'css-loader' } ) },
|
2015-12-19 14:52:17 +01:00
|
|
|
{ test: /\.(woff2?|ttf|eot|svg|png|jpe?g|gif)$/,
|
|
|
|
loader: 'file' }
|
|
|
|
]
|
|
|
|
},
|
|
|
|
plugins: [
|
2017-06-14 19:55:04 +02:00
|
|
|
new ExtractTextPlugin({
|
|
|
|
filename: 'styles.css',
|
2015-12-19 14:52:17 +01:00
|
|
|
allChunks: true
|
|
|
|
}),
|
|
|
|
new webpack.optimize.UglifyJsPlugin()
|
|
|
|
]
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
## Creating the App
|
|
|
|
|
|
|
|
Now we can start building our app. We configured at least two files
|
|
|
|
in webpack: `js/main.js` and `scss/main.scss`. Those are the entry
|
|
|
|
points we need to have. You can create them as empty files in
|
|
|
|
`webpack/js/main.js` and `webpack/scss/main.scss`.
|
|
|
|
|
|
|
|
## Running the Server
|
|
|
|
|
|
|
|
Now you're ready to go. When you run `lektor server` webpack will not
|
|
|
|
run, instead you need to now run it with the `webpack` flag which
|
|
|
|
will enable the webpack build:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ lektor server -f webpack
|
|
|
|
```
|
|
|
|
|
|
|
|
Webpack automatically builds your files into `assets/static/gen` and this is
|
|
|
|
where Lektor will then pick up the files. This is done so that you can ship
|
|
|
|
the webpack generated assets to others that do not have webpack installed which
|
|
|
|
simplifies using a Lektor website that uses webpack.
|
|
|
|
|
|
|
|
## Manual Builds
|
|
|
|
|
|
|
|
To manually trigger a build that also invokes webpack you can also pass
|
|
|
|
the `webpack` flag there:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ lektor build -f webpack
|
|
|
|
```
|
|
|
|
|
|
|
|
## Including The Files
|
|
|
|
|
|
|
|
Now you need to include the files in your template. This will do it:
|
|
|
|
|
|
|
|
```html+jinja
|
|
|
|
<link rel="stylesheet" href="{{
|
|
|
|
'/static/gen/styles.css'|asseturl }}">
|
|
|
|
<script type=text/javascript src="{{
|
|
|
|
'/static/gen/app.js'|asseturl }}" charset="utf-8"></script>
|
|
|
|
```
|