webpack入门详解

写在前面

上一篇文章里面讲到前端模块化的基本概念,同时用webpack进行打包演示了一个基础的hello world实例,webpack的内容肯定不止那么多,在这篇文章里面我会详细介绍webpack的使用细节。同时,会结合vue.js完成一个更加实用的例子。如果你还没有看上一篇内容,建议你先阅读相关的内容,再看本篇文章效果会更好。

小伙伴戳这里 → 浅析前端模块化

webpack插件详解

在讲解插件之前我们先说明一下接下来的实例的目录结构如下:

  • 项目名/
  • ├── dist //打包之后最终部署到服务器上的文件(名称自定义)
  • ├── src //资源文件(名称自定义)
  • ├── node_modules //在打包过程中依赖的包
  • ├── package.json //包含各种所需模块以及项目的配置信息。
  • └── webpack.config.js //打包配置文件

package.json包含可配置项

  • name 名称
  • description 应用描述
  • version 版本号
  • config 应用的配置项
  • author 作者
  • respository 资源仓库地址
  • licenses 授权方式
  • directories 目录
  • main 应用入口文件
  • bin 命令行文件
  • dependencies 项目应用运行依赖模块
  • devDependencies 项目应用开发环境依赖
  • engines 运行引擎
  • script 脚本

这里沿用上一篇文章中的代码,不过要稍微修改一下,将下面的index.js和sub.js放在src文件夹下面。 index.js:

//引用sub模块
var sub = require('./sub');

var app=document.createElement('div');
app.innerHTML="hello world";
app.appendChild(sub());
document.body.appendChild(app);

sub.js:

//我们这里使用CommonJS的风格
function getText(){
  var element = document.createElement('h2');
  element.innerHTML = "Hello China";
  return element;
}

module.exports = getText;

html-webpack-plugin

这是一个webpack自动生成html文件的插件,在上一篇博客hello world那个例子中当我们合并合并了js,然后是手动的新建html文件并引用了生成的bundle.js文件,这里我们引用一个html-webpack-plugin插件,可以实现自动生成html模板文件。

执行下面的代码在命令行安装:

npm install html-webpack-plugin --save-dev

安装完这个插件,开始写webpack.config.js文件:

var path = require('path');
var HtmlwebpackPlugin = require('html-webpack-plugin');

//定义了一些文件夹的路径
var ROOT_PATH = path.resolve(__dirname);
var SRC_PATH = path.resolve(ROOT_PATH, 'src');
var DIST_PATH = path.resolve(ROOT_PATH, 'dist');

module.exports = {
  //项目的文件夹 可以直接用文件夹名称 默认会找index.js 也可以确定是哪个文件名字
  entry: SRC_PATH,
  //输出的文件名 合并以后的js会命名为bundle.js
  output: {
    path: DIST_PATH,
    filename: 'bundle.js'
  },
  //添加我们的插件 会自动生成一个html文件
  plugins: [
    new HtmlwebpackPlugin({
      title: 'Hello World'
    })
  ]
};

然后在项目根目录运行webpack,终端显示一堆信息,然后告诉你成功了,你会发现在dist文件夹下生成了一个index.html文件,点开这个文件你会发现和上一篇的效果一样。

webpack-dev-server

上面任务虽然完成了,但是我们修改了要不断运行程序然后刷新页面,所以最好新建一个开发服务器,可以serve我们pack以后的代码,并且当代码更新的时候自动刷新浏览器。

执行下面的代码在命令行安装:

npm install webpack-dev-server --save-dev

安装完毕后,在webpack.config.js中添加配置:

module.exports = {
  ....
  devServer: {
    historyApiFallback: true,
    hot: true,
    inline: true,
    progress: true,
  },
  ...
}

然后再package.json里面配置一下运行的命令,npm支持自定义一些命令

...
"scripts": {
  "start": "webpack-dev-server --hot --inline"
},
...

好了,万事具备了,在项目根目录下输入npm start,一堆花花绿绿的信息后server已经起来了,在浏览器里面输入http://localhost:8080,发现伟大的hello world出现了,在js里面随便修改一些输出然后保存!这里我把sub.js里面的内容改为:

element.innerHTML = "Hello China,I am zhaomenghuan";

浏览器自动刷新,新的结果出现了。

对比一下:

这个是直接打开的结果: 这个是webpack-dev-server下的结果: 这里我们可以看出来webpack-dev-server自动帮我们进行了内容的更新,这样避免了我们修改一下内容就要重新打包一下、刷新浏览器等一系列琐碎的事,我们只需要在最后部署的时候使用webpack命令打包一下就ok了。

css-loader style-loader

现在来添加一些样式,webpack使用loader的方式来处理各种各样的资源,比如说样式文件,我们需要两种loader,css-loader 和 style-loader,css-loader会遍历css文件,找到所有的url(...)并且处理。style-loader会把所有的样式插入到你页面的一个style tag中。

安装我们的loader:

npm install css-loader style-loader --save-dev

在webpack.config.js中配置loader:

...
  module: {
    loaders: [
      {
        test: /\.css$/,
        loaders: ['style', 'css']
      }
    ]
  },
...

在新建一个样式文件 style.css

body{
  background-color: #f00;
}

记得在入口文件index.js中引用

require('./style.css');

然后发现页面背景颜色变成红色的了,webpack的理念是基于项目处理的,把对应的文件格式给对应的loader处理,然后你就不用管了,它会决定怎么压缩,编译。

那现在想使用一些有爱的css预编译程序,来点sass吧。你可能已经想到了,再来个loader就行啦,确实是这样简单。

不过特别注意:这里还需要添加node-sass来解析sass文件。

npm install sass-loader node-sass --save-dev

稍微修改一下webpack.config.js,删掉我们先前添加的css规则,加上下面的loader

loaders: [
  {
    test: /\.scss$/,
    loaders: ['style', 'css','sass']
  }
]

添加两个sass文件,variables.scss和style.scss

variables.scss:

$blue: blue;

style.scss:

import "./variables.scss";

body{
  background-color: blue;
}

在index.js中引用:

require('./style.scss');

然后会发现页面背景颜色变成了蓝色。

url-loader

上面的css-loader、style-loader、sass-loader主要是用于处理样式文件,这里url-loader用于处理图片文件的。

安装url-loader

npm install url-loader --save-dev

配置config文件

{
	test: /\.(png|jpg)$/,
	loader: 'url-loader?limit=40000'
}

注意后面那个limit的参数,当你图片大小小于这个限制的时候,会自动启用base64编码图片。

pic.js:

// 我们这里使用CommonJS的风格
function getImg(){
  var img = document.createElement("img");
  img.src = require("./demo.png");
  return img;
}

module.exports = getImg;

在index.js里面添加如下内容:

var pic = require('./pic');
app.appendChild(pic());

如果不能显示,先使用webpack命令,然后使用npm start启动服务器,在http://localhost:8080/查看效果,打开浏览器控制台然后查看图片的url,发现为base64编码图片。

babel-loader babel-preset-es2015

如果你想通过项目熟悉一下ES6,那么你可以ES6的语法支持,但是考虑兼容性的问题,我们可以使用babel处理。

安装loader

npm install babel-loader babel-preset-es2015 --save-dev

配置我们的webpack.config.js文件

...
  {
    test: /\.jsx?$/,
    loader: 'babel',
    query: {
      presets: ['es2015']
    }
  },
...

es2015这个参数是babel的plugin,可以支持各种最新的es6的特性,现在我们可以改掉CommonJS风格的文件了。

sub.js:

//我们这里使用CommonJS的风格
export default function(){
  var element = document.createElement('h2');
  element.innerHTML = "Hello China,I am Chinese";
  return element;
}

index.js:

import sub from './sub';

通过import语句引入后加载模块时,可以为模块匿名函数指定任意名字。

参考文章

纯扯淡

最近在准备暑期实习生的面试,感慨万千,感觉真的越来越渴望进入前端这个行业成为一个真正的前端工程师,也希望各位朋友可以坚持自己的爱好,不要放弃,勇敢去追求,我相信我们都会成实现的。也真正体会到其实之前很多担忧是多余的,如果真的有技术,不用太在乎是不是计算机专业,因为一个人的天赋和潜力和所处的环境不一定是完全相关的,潜下心去钻研或许更好。

写这些代码也许就一两个小时的事,写一篇大家好接受的文章需要几天的酝酿,如果文章对您有帮助请我喝杯咖啡吧!