浅谈webpack最强大的功能——Loaders

1、Loaders

Loaderswebpack中最强大的功能之一了。通过使用不同的loaderwebpack通过调用外部的脚本或工具可以对各种各样的格式的文件进行处理,如分析JSON文件并把它转换为JavaScript文件;或把下一代的JS文件(ES6ES7)转换为现代浏览器可以识别的JS文件;或对React的开发而言,合适的Loaders可以把ReactJSX文件转换为JS文件。

Loaders需要单独安装并且需要在webpack.config.js下的modules关键字下进行配置。安装命令为npm install --save-dev json-loader,Loaders的配置选项包括以下几方面:

modules配置选项

功能描述

test

一个匹配loaders所处理的文件的拓展名的正则表达式(必须)

loader

loader的名称(必须)

include/exclude

手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选)

query

为loaders提供额外的设置选项(可选)

继续上面的例子,把Greeter.js里的问候消息放在一个单独的JSON文件里,并通过合适的配置使Greeter.js可以读取该JSON文件的值,配置方法如下:

module.exports = {
  	devtool: 'eval-source-map', // 配置生成Source Maps,选择合适的选项
	entry:  __dirname + "/app/main.js", // 已多次提及的唯一入口文件
	output: {
		path: __dirname + "/public", // 打包后的文件存放的地方
		filename: "bundle.js" // 打包后输出文件的文件名
	},
	module: { // 在配置文件里添加JSON loader
		loaders: [
			{
				test: /\.json$/,
				loader: "json-loader"
			}
		]
	},
  	devServer: {
    	contentBase: "./public", // 本地服务器所加载的页面所在的目录
    	colors: true, // 终端中输出结果为彩色
    	historyApiFallback: true, // 不跳转
    	inline: true // 实时刷新
  	}
}

创建带有问候信息的JSON文件config.json:

{
  	"greetText": "Hi there and greetings from JSON!"
}

更新后的Greeter.js:

var config = require('./config.json');
module.exports = function() {
  	var greet = document.createElement('div');
  	greet.textContent = config.greetText;
  	return greet;
};

按照上面提到的结果查看方法即可查看结果:

访问file:///D:/nodejs/public/index.html,可得输出:

Hi there and greetings from JSON!

 

2、Babel

Loaders很好,不过有的Loaders使用起来比较复杂,如Babel。

Babel其实是一个编译JavaScript的平台,它的强大之处表现在可以通过编译达到以下目的:

1) 下一代的JavaScript标准(ES6,ES7),这些标准目前并未被当前的浏览器完全的支持;

2) 使用基于JavaScript进行了拓展的语言,如React的JSX。

Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中,不过webpack把它们整合在一起使用,但是对于每一个需要的功能或拓展,都需要安装单独的包(用得最多的是解析Es6的babel-preset-es2015包和解析JSX的babel-preset-react包)。

一次性安装这些依赖包(npm一次性安装多个依赖模块,模块之间用空格隔开):

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

在webpack中配置Babel的方法如下(在webpack.config.js的module部分的loaders里进行配置即可):

module.exports = {
  	devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
	entry:  __dirname + "/app/main.js",//已多次提及的唯一入口文件
	output: {
		path: __dirname + "/public",//打包后的文件存放的地方
		filename: "bundle.js"//打包后输出文件的文件名
	},
	module: {
		loaders: [
			{
				test: /\.json$/,
				loader: "json-loader"
			},
			{
				test: /\.js$/,
				exclude: /node_modules/,
				loader: 'babel',
				query: {
					presets: ['es2015','react']
				}
			}
		]
	},
  	devServer: {
    	contentBase: "./public", // 本地服务器所加载的页面所在的目录
    	colors: true, // 终端中输出结果为彩色
    	historyApiFallback: true, // 不跳转
    	inline: true // 实时刷新
  	}
}

webpack进行以上配置后,允许使用ES6以及JSX的语法。

使用React,上面的例子进行测试。先安装 React 和 React-DOM,安装命令为npm install --save react react-dom。

使用ES6的语法,更新Greeter.js并返回一个React组件

import React, {Component} from 'react';
import config from './config.json';
class Greeter extends Component{
  	render() {
    	return (
      		<div>
        		{config.greetText}
      		</div>
    	);
  	}
}
export default Greeter

使用ES6的模块定义和渲染Greeter模块:

import React from 'react';
import {render} from 'react-dom';
import Greeter from './Greeter';
render(<Greeter />, document.getElementById('root'));

Babel的配置选项:

Babel其实可以完全在webpack.config.js中进行配置,但考虑到babel具有非常多的配置选项,在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂,因此一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中。现在的babel的配置并不算复杂,不过之后会再加一些东西,因此现在就提取出相关部分,分两个配置文件进行配置(webpack会自动调用.babelrc里的babel配置选项),如下:

module.exports = {
  	devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
	entry:  __dirname + "/app/main.js",//已多次提及的唯一入口文件
	output: {
		path: __dirname + "/public",//打包后的文件存放的地方
		filename: "bundle.js"//打包后输出文件的文件名
	},
	module: {
		loaders: [
			{
				test: /\.json$/,
				loader: "json-loader"
			},
			{
				test: /\.js$/,
				exclude: /node_modules/,
				loader: 'babel'
			}
		]
	},
  	devServer: {
    	contentBase: "./public", // 本地服务器所加载的页面所在的目录
    	colors: true, // 终端中输出结果为彩色
    	historyApiFallback: true, // 不跳转
    	inline: true // 实时刷新
  	}
}

.babelrc:

{
  	"presets": ["react", "es2015"]
}

 

3、模块

webpack的优点:把所有的文件都可以当做模块处理,包括JavaScript代码,也包括CSS和fonts以及图片等,通过合适的loaders,它们都可以被当做模块被处理。

1)CSS

webpack提供两个工具处理样式表,css-loader 和 style-loader,二者处理的任务不同,css-loader使得能够使用类似@import 和 url(...)的方法实现 require()的功能,style-loader将所有的计算后的样式加入页面中,二者组合在一起能够把样式表嵌入webpack打包后的JS文件中。

安装命令:npm install --save-dev style-loader css-loader

module.exports = {
  	devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
	entry:  __dirname + "/app/main.js",//已多次提及的唯一入口文件
	output: {
		path: __dirname + "/public",//打包后的文件存放的地方
		filename: "bundle.js"//打包后输出文件的文件名
	},
	module: {
		loaders: [
			{
				test: /\.json$/,
				loader: "json-loader"
			},
			{
				test: /\.js$/,
				exclude: /node_modules/,
				loader: 'babel',
				query: {
					presets: ['es2015','react']
				}
			},
			{
				test: /\.css$/,
				loader: 'style!css'
			}
		]
	},
  	devServer: {
    	contentBase: "./public", // 本地服务器所加载的页面所在的目录
    	colors: true, // 终端中输出结果为彩色
    	historyApiFallback: true, // 不跳转
    	inline: true // 实时刷新
  	}
}

注:感叹号的作用在于使同一文件能够使用不同类型的loader。

在app文件夹里创建main.css:

html {
	box-sizing: border-box;
	-ms-text-size-adjust: 100%;
	-webkit-text-size-adjust: 100%;
}
*, *:before, *:after {
	box-sizing: inherit;
}
body {
	margin: 0;
	font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
h1, h2, h3, h4, h5, h6, p, ul {
	margin: 0;
	padding: 0;
}

webpack只有单一的入口,其它的模块需要通过 import, require, url等导入相关位置,为了让webpack能找到main.css文件,把它导入main.js 中,如下:

import React from 'react';
import {render} from 'react-dom';
import Greeter from './Greeter';
import './main.css';//使用require导入css文件
render(<Greeter />, document.getElementById('root'));

通常情况下,css会和js打包到同一个文件中,并不会打包为一个单独的css文件,不过通过合适的配置webpack也可以把css打包为单独的文件的。


2)CSS modules

CSS modules 的技术就意在把JS的模块化思想带入CSS中来,通过CSS模块,所有的类名,动画名默认都只作用于当前模块。Webpack从一开始就对CSS模块化提供了支持,在CSS loader中进行配置后,所需要做的一切就是把modules传递都所需要的地方,然后就可以直接把CSS的类名传递到组件的代码中,且这样做只对当前组件有效,不必担心在不同的模块中具有相同的类名可能会造成的问题。具体的代码如下:

module.exports = {
  	devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
	entry:  __dirname + "/app/main.js",//已多次提及的唯一入口文件
	output: {
		path: __dirname + "/public",//打包后的文件存放的地方
		filename: "bundle.js"//打包后输出文件的文件名
	},
	module: {
		loaders: [
			{
				test: /\.json$/,
				loader: "json-loader"
			},
			{
				test: /\.js$/,
				exclude: /node_modules/,
				loader: 'babel',
				query: {
					presets: ['es2015','react']
				}
			},
			{
				test: /\.css$/,
				loader: 'style!css?modules'
			}
		]
	},
  	devServer: {
    	contentBase: "./public", // 本地服务器所加载的页面所在的目录
    	colors: true, // 终端中输出结果为彩色
    	historyApiFallback: true, // 不跳转
    	inline: true // 实时刷新
  	}
}

创建一个Greeter.css文件:

.root {
  	background-color: #eee;
  	padding: 10px;
  	border: 3px solid #ccc;
}

导入.root到Greeter.js中

import React, {Component} from 'react';
import config from './config.json';
import styles from './Greeter.css';//导入
class Greeter extends Component{
  	render() {
    	return (
      		<div className={styles.root}>//添加类名
        		{config.greetText}
      		</div>
    	);
  	}
}
export default Greeter


3、CSS预处理器

有关Less Loader、Sass Loader、Stylus Loader的介绍请见:http://blog.csdn.net/zhouziyu2011/article/details/67646875

还有一个CSS的处理平台-PostCSS,可以帮助CSS实现更多的功能,使用PostCSS来为CSS代码自动添加适应不同浏览器的CSS前缀。

安装postcss-loader 和 autoprefixer(自动添加前缀的插件):npm install --save-dev postcss-loader autoprefixer。

在webpack.config.js中进行设置,只需要新建一个postcss关键字,并在里面申明依赖的插件,css会自动根据数据添加不同前缀了。

module.exports = {
  	devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
	entry:  __dirname + "/app/main.js",//已多次提及的唯一入口文件
	output: {
		path: __dirname + "/public",//打包后的文件存放的地方
		filename: "bundle.js"//打包后输出文件的文件名
	},
	module: {
		loaders: [
			{
				test: /\.json$/,
				loader: "json-loader"
			},
			{
				test: /\.js$/,
				exclude: /node_modules/,
				loader: 'babel',
				query: {
					presets: ['es2015','react']
				}
			},
			{
				test: /\.css$/,
				loader: 'style!css?modules!postcss'
			}
		]
	},
	postcss: [
    	require('autoprefixer')//调用autoprefixer插件
  	],
  	devServer: {
    	contentBase: "./public", // 本地服务器所加载的页面所在的目录
    	colors: true, // 终端中输出结果为彩色
    	historyApiFallback: true, // 不跳转
    	inline: true // 实时刷新
  	}
}

处理JS的Babel和处理CSS的PostCSS其实也是两个单独的平台,配合Webpack可以很好的发挥它们的作用。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值