webpack的学习(
webpack是单一入口, 其它的模块需要通过 import, require, url等导入相关位置)
nodjs语法说明
module.exports = MATH; // MATH.js文件下
如何调用这个模块?
var a = require("./MATH.js")
ES6语法说明
传出模块
export {name1,name2,name3};
接收模块
import {name1,name2,name3} from "xx.js" //选择加载的模块
安装webpack
//全局安装
npm install -g webpack
//安装到你的项目目录
npm install --save-dev webpack
npm install -g webpack
//安装到你的项目目录
npm install --save-dev webpack
安装package.json(
包括当前项目的依赖模块,自定义的脚本任务等等) 一路回车即可
npm init
创建项目结构
,app文件夹和public文件夹,app文件夹用来存放原始数据和我们将写的JavaScript模块,public文件夹用来存放准备给浏览器读取的数据(包括使用webpack生成的打包后的js文件以及一个index.html文件)。在这里还需要创建三个文件,index.html 文件放在public文件夹中,两个js文件(Greeter.js和main.js)放在app文件夹中,此时项目结构如下图所示
index.html 主页
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Webpack Sample Project</title>
</head>
<body>
<div id='root'>
<meta charset="utf-8">
<title>Webpack Sample Project</title>
</head>
<body>
<div id='root'>
</div>
<script src="../bundle.js"></script> //引入的是打包后的bundle.js
</body>
</html>
Greeter.js 模块
// Greeter.js(传递是一个模块函数)
module.exports = function() {
var greet = document.createElement('div');
greet.textContent = "Hi there and greetings!";
return greet;
};
main.js 入口函数(接收模块)webpack编译的时候,需要入口函数和webpack自动打包后的函数
//main.js
var greeter =
require('./Greeter.js'); //接收Greeter模块
document.getElementById('root').appendChild(greeter());
使用webpack打包(全局安装webpack的情况下)
webpack 入口文件 打包后文件
webpack app/main.js bundle.js
编译成功
同时编译了main,js 和 Greeter,js
webpack 另一种使用的方法
通过webpack.config.js
注
:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
配置
module.exports = {
entry: "./app/main.js",//已多次提及的唯一入口文件
output: {
path: __dirname,//打包后的文件存放的地方
filename: "bundle.js"//打包后输出文件的文件名
}
}
运行webpack编译
webpack
更便捷的打包方法
简化命令行
在package.json配置
添加
"scripts": {
"start": "webpack" //配置的地方就是这里啦,相当于把npm的start命令指向webpack命令
},
可以通过
npm start 运行
Source Maps
在webpack的配置文件webpack.config.js里配置
上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的构建速度的后果就是对打包后的文件的的执行有一定影响。
devtool : ...
module.exports = {
devtool: 'source-map',
entry: "./app/main.js",//已多次提及的唯一入口文件
output: {
path: __dirname,
filename: "bundle.js"//打包后输出文件的文件名
}
}
热加载(webpack自带端口号为8080的服务器,不需要开启wamp)
安装组件
npm install --save-dev webpack-dev-server
配置webpack.config.js(devServer)
inline 是否实时刷新
package.json
"start": "webpack-dev-server --inline",
module.exports = {
devtool: 'eval-source-map',
entry: __dirname + "/app/main.js",
output: {
path: __dirname + "/public",
filename: "bundle.js"
output: {
path: __dirname + "/public",
filename: "bundle.js"
},
devServer: {
contentBase: "./public",//本地服务器所加载的页面所在的目录
port: 8080,
colors: true,//终端中输出结果为彩色
historyApiFallback: true,//不跳转
inline: true//实时刷新
}
historyApiFallback: true,//不跳转
inline: true//实时刷新
}
}
开启服务
webpack-dev-server
浏览器使用打开
http://localhost:8080/webpack-dev-server/
各种各样的loader
用处:
分析JSON文件并把它转换为JavaScript文件,或者说把下一代的JS文件(ES6,ES7)转换为现代浏览器可以识别的JS文件。或者说对React的开发而言,合适的Loaders可以把React的JSX文件转换为JS文件。
配置在webpack.config.js的modules
参数
test
:一个匹配loaders所处理的文件的拓展名的正则表达式(必须)loader
:loader的名称(必须)include/exclude
:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);query
:为loaders提供额外的设置选项(可选)
loader的安装(这只是json-loader)
npm install --save-dev json-loader
webpack.config.js的配置
module : {
loaders : [
{
test: /\.json$/, //匹配后缀名
loader: “json” //loader的名称
}
]
}
config要与引用他的Greeter.js模块在同一个目录下
创建一个config.json(json-loader可以解析json文件)
注意JSON文件不能写注释
json 文件也可以直接用 require来引用的,而且文件里面直接写 json,不用写 module.exports,引用后也不用 parse
//config.json
{
"greetText": "Hi there and greetings from JSON!"
}
{
"greetText": "Hi there and greetings from JSON!"
}
修改Greeter模块。引入Greeter模块
var config = require('./config.json');
module.exports = function() {
var greet = document.createElement('div');
greet.textContent = config.greetText;
return greet;
};
module.exports = function() {
var greet = document.createElement('div');
greet.textContent = config.greetText;
return greet;
};
config.json是一个模块,Greeter.js是一个模块。Greeter引用config.json模块,入口函数,引用Greeter模块。json-loader或者说loader就是对不同文件进行处理
Bable
Bable是一些列的包,安装一系列的代码依赖
// npm一次性安装多个依赖模块,模块之间用空格隔开
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
配置Bable
Babel其实可以完全在webpack.config.js中进行配置,但是考虑到babel具有非常多的配置选项,在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂,因此一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中。我们现在的babel的配置并不算复杂,不过之后我们会再加一些东西,因此现在我们就提取出相关部分,分两个配置文件进行配置(webpack会自动调用
.babelrc
里的babel配置选项)
webpack.config.js配置Bable
{
test: /\.js$/,
exclude : /node_modules/,
不需要处理的文件夹
loader: 'babel' babel-loader,
query: {
presets: ['es2015']
//可以解析es6的代码
}
}
创建 .babelrc 由于win系统下无法创建没有文件名的文件。可以使用webStorm或者sublime的软件创建
{
"presets": ["es2015", "stage-2"], //转换es6代码和es7第二阶段的代码
"plugins": ["transform-runtime"], //转换APi,一些方法不转换api无法使用,例如字符串的includes()
"comments": false
}
CSS css-loader 和 style-loader
css-loader
使你能够使用类似
@import
和
url(...)
的方法实现
require()
的功能,
style-loader
将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。
安装
npm install --save-dev style-loader css-loader
配置webpack.config.js
{
test : /\.css$/, //解析.css的文件
loader : 'style!css' //css-loader 和 style-loader !能够使用不同的loader
}
由于webpack只能从main.js入口进入,需要把main.css导入到main.js
可以使用es6的新语法(bable配置了ES2015的语法)
import './main.css';//使用require导入css文件
css-module
CSS modules 的技术就意在把JS的模块化思想带入CSS中来,通过CSS模块,所有的类名,动画名默认都只作用于当前模块。Webpack从一开始就对CSS模块化提供了支持,在CSS loader中进行配置后,你所需要做的一切就是把”modules“传递都所需要的地方,然后就可以直接把CSS的类名传递到组件的代码中,且这样做只对当前组件有效,不必担心在不同的模块中具有相同的类名可能会造成的问题。
webpack.config.js配置css-module
{
test: /\.css$/,
loader: 'style!css?modules'//跟前面相比就在后面加上了?modules
}
创建一个某个模块对应的css模块(Greeter.js 模块所对应的 Greeter.css模块)
.ro{
background-color: #eee;
padding: 10px;
border: 3px solid #ccc;
padding: 10px;
border: 3px solid #ccc;
}
将Greeter.css 模块 导入Greeter.js模块
import styles from './Greeter.css';
import config from './config.json';
module.exports = function() {
var greet = document.createElement('div');
greet.className = styles.ro;
greet.textContent = config.greetText;
return greet;
};
好处就是
同的类名也不会造成不同组件之间的污染。
css-module的官方文档地址
https://github.com/css-modules/css-modules
CSS预处理器
Sass 和 Less之类的预处理器是对原生CSS的拓展,它们允许你使用类似于variables, nesting, mixins, inheritance等不存在于CSS中的特性来写CSS,CSS预处理器可以这些特殊类型的语句转化为浏览器可识别的CSS语句
- Less Loader
- Sass Loader
- Stylus Loader
不过其实也存在一个CSS的处理平台-PostCSS,它可以帮助你的CSS实现更多的功能,在其CSS官方文档可了解更多相关知识。举例来说如何使用PostCSS,我们使用PostCSS来为CSS代码自动添加适应不同浏览器的CSS前缀。
首先安装postcss-loader 和 autoprefixer(自动添加前缀的插件)
npm install --save-dev postcss-loader autoprefixer
配置webpack.config.js
只需要新建一个postcss关键字,并在里面申明依赖的插件,如下,现在你写的css会自动根据Can i use里的数据添加不同前缀了。
postcss: [
require('autoprefixer')//调用autoprefixer插件
],
处理JS的Babel和处理CSS的PostCSS,它们其实也是两个单独的平台,配合Webpack可以很好的发挥它们的作用
插件(Plugins)
插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。
Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。
使用插件的方法
要使用某个插件,我们需要通过npm安装它,然后要做的就是在webpack配置中的plugins关键字部分添加该插件的一个实例(plugins是一个数组)
插件的安装(介绍一些插件)
HtmlWebpackPlugin插件
这个插件的作用是依据一个简单的模板,帮你生成最终的Html5文件,这个文件中自动引用了你打包后的JS文件。每次编译都在文件名中插入一个不同的哈希值。
//下载
npm install --save-dev html-webpack-plugin
配置webpack.config.js(使用插件)
plugins: [
new HtmlWebpackPlugin({
template: __dirname + "/app/index.tmpl.html"
//new 一个这个插件的实例,并传入相关的参数,调用这个插件
})
],
优化插件
webpack提供了一些在发布阶段非常有用的优化插件,它们大多来自于webpack社区,可以通过npm安装,通过以下插件可以完成产品发布阶段所需的功能
- OccurenceOrderPlugin :为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID
- UglifyJsPlugin:压缩JS代码;
- ExtractTextPlugin:分离CSS和JS文件
我们继续用例子来看看如何添加它们,OccurenceOrder 和 UglifyJS plugins 都是内置插件,你需要做的只是安装它们
npm install --save-dev extract-text-webpack-plugin
在webpack.config.js引用他们
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin("style.css")
]