上篇文章中简单介绍了webpack的最基本用法,且项目结构十分简单,只有一个html
页面、一个css
页面、两个js
文件。本文将介绍如何使用webpack对具有较为规范的结构的项目进行构建。主要包括以下几个方面:
进一步了解
webpack.config.js
进一步了解
webpack-dev-server
使webpack支持es6语法
关于webpack.config.js
我们以最常用最简单的项目结构来演示,如下:
myPro
- css
- src
- node-modules
- dist
- index.html
- webpack.config.js
这样我们的项目结构就很清晰了。css
文件夹中存放样式文件,src
文件夹中存放js
文件,node-modules
中是我们用到的各种包,dist
文件存放打包生成的文件。现在我希望做到以下两点
css
使用less
编写打包文件到
dist
目录下
第一步,在css
文件夹中创建以下两个文件index.less
@import 'demo.less';
demo.less
body {
background: yellow;
.main {
width: 200px;
height: 200px;
border: 10px solid red;
}
}
第二步,在src
文件夹中创建文件content.js
module.exports = 'it works from content.js';
entry.js
require('../css/index.less');
let content = require('./content.js');
alert(content);
第三部,修改index.html
如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>webpack demo</title>
</head>
<body>
<div class="main" id="main">
<p>webpack demo</p>
</div>
</body>
<script type="text/javascript" src="./dist/bundle.js"></script>
</html>
至此,我们看到 1、样式文件使用了less编写;2、在index.html
页面中js
文件路径为./dist/bundle.js
。
配置less-loader
对于1(样式文件采用less
编写),我们需要使用加载器来处理。首先,需要安装less-loader
,而less-loader
依赖于less
,因此需要这样安装
$ npm install less-loader less
然后再config文件中配置对less文件的处理,如下:
module: {
loaders: [
{
test: /\.css$/,
loader: "style!css"
},
{
test: /\.less$/,
loader: "style!css!less"
}
]
}
这里加入了对less
文件的处理,需要注意loader
的顺序,为style!css!less
,意为先使用less
加载器处理,解析为普通的css
文件,再处理css
文件,最后处理样式,类似于pipe
的概念。
设置output
在上篇文章中,我们提到了webpack.config.js文件中可以设置output
,作为打包的出口参数。如下:
output: {
path: __dirname,
filename: "bundle.js"
}
这里设置了两项:path
和filename
其中,path
为打包的目录,__dirname
指当前目录,filename
指文件名。
这里我们希望将文件打包到dist目录下,则可以通过配置path
来实现,完整配置如下:
let path = require('path');
module.exports = {
entry: "./src/entry.js",
output: {
path: path.join( __dirname, '/dist'), //这里配置打包路径
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.css$/,
loader: "style!css"
},
{
test: /\.less$/,
loader: "style!css!less"
}
]
}
};
至此,我们完成了两步,1、对less
文件正确处理; 2、将文件打包到dist
目录下。
打包:
$ webpack
用浏览器打开index.html
页面,可以看到:
进一步了解webpack-dev-server
上篇文章提到,webpack-dev-server为我们提供了一个小型的基于node的express服务器,使我们可以通过http://localhost:8080/webpack-dev-server/
来访问页面,并且它可以监测文件的变化并在页面中实时显示出来。现在我们再来试下:
启动webpack-dev-server
$ webpack-dev-server
访问http://localhost:8080/webpack-dev-server/
修改content.js
文件如下:
module.exports = 'it is another content from content.js';
可以看到,页面自动进行了刷新,但是alert
的内容却没有变。这说明监测到了文件的变化,但是我们的index.html
加载的js文件并没有变。
那问题出在哪里?
webpack-dev-server
原理
webpack-dev-server通过sockjs
实现实时变化监测,当文件变化时,服务器就会向客户端发送通知,客户端重新渲染。
每次文件变化都会触发webpack-dev-server对文件进行重新编译,但是这个编译后的文件并不会每次都保存到我们的dist目录下,而是存放在内存中,默认情况下,这个文件的路径为当前路径。也就是说,每次文件变化后,内存中的bundle.js
做出了实时的变化,而output
中配置的文件其实并没有变。也就是说,如果我们在index.html
中使用./bundle.js
则能够实现页面内容的实时更新。
那么,如何配置可以使其支持我们当前的写法./dist/bunlde.js
呢?就需要用到publicPath
这个属性。
output
的publicPath
属性
webpack-dev-server默认支持文件路径为当前的路径,可以通过在output
中配置publicPath
属性对其进行更改,如下:
output: {
path: path.join( __dirname, '/dist'),
publicPath: '/dist/',
filename: "bundle.js"
}
这样设置我们就可以通过./dist/bundle.js
路径访问到内存中的文件,在当前路径下已经存在同名文件的情况下,webpack-dev-server会优先使用内存中的文件。
至此,我们已经实现了:
使用less编写样式文件
将文件打包到指定目录
监测文件变化并实时展示
看到,现在我们还是采用的commonJS
的规范来实现模块化,而es6
为我们提供了export
和import
语法来支持模块化,如果想要在项目中使用es6
,同样可以通过webpack
来配置实现。
webpack
支持es6
使webpack
支持es6
需要用到babel,它可以帮助我们将es6语法转化为es5的格式,可以在这里测试。
首先,需要安装babel
$ npm install babel-loader babel-core
安装babel-preset
$ npm install babel-preset-es2015
然后,配置webpack.config.js
,如下:
module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
]
}
最后还需要加上babel的配置文件,在项目的根目录下创建文件.babelrc
{ "presets": ["es2015"] }
这样,我们的webpack
就支持通过es6
的export
和import
实现模块化了。
修改content.js
内容如下:
var content = 'it is the origin content from content.js';
export {content};
修改entry.js
内容如下:
require('../css/index.less');
import {content} from './content';
let div = document.getElementById('main');
div.innerHTML = content;
可以看到,我们现在通过es6
的import
和export
实现js
的模块化,打包:
$ webpack
打包成功。
结语
本文介绍了如何使用webpack对一个较为系统的项目进行打包,并支持less
,es6
,同时对webpack-dev-server
的原理进行了简要说明。后续还会更深入地学习webpack,希望和大家一同进步。
(本文完)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。