中简单介绍了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
如下:
webpack demo webpack demo
至此,我们看到 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
访问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
实现实时变化监测,当文件变化时,服务器就会向客户端发送通知,客户端重新渲染。
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的格式,可以在测试。
$ 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,希望和大家一同进步。
(本文完)