为什么用Webpack
- 模块化,让我们可以把复杂的程序细化为小的文件;
- 类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能转换为JavaScript文件使浏览器可以识别;
- Scss,less等CSS预处理器等等
- 。。。
Webpack是什么
Webpack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
Webpack工作方式
把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。
简单使用教程
使用npm安装
//全局安装
npm install webpack -g
//安装到你的项目目录
npm install webpack --save-dev
创建package.json
在上述练习文件夹中创建一个package.json文件,这是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等等。在终端中使用npm init命令可以自动创建这个package.json文件
npm init
例:
{
"name": "05_html",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"dev": "webpack --config ./webpack.config.js"
// !!!JSON文件不支持注释,引用时请清除
//运行命令 npm run dev , node 会去运行webpack.config.js
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"css-loader": "^1.0.1",
"file-loader": "^2.0.0",
"html-webpack-plugin": "^3.2.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.0"
}
}
创建webpack.config.js
webpack.config.js是对于webpack的一些配置
例:
const path = require('path');
module.exports = {
entry: __dirname + "/src/main.js",
//已多次提及的唯一入口文件,app文件夹下的main.js
//注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
output: {
//指定产出的目录
//path:path.resolve(__dirname,'./public'),
path: __dirname + "/public",
//打包后的文件存放的地方
filename: "bundle.js"//打包后输出文件的文件名
},
watch: true, //文件发生改动,自动监视,自动产出bundle.js
}
使用webpack构建本地服务器
想不想让你的浏览器监听你的代码的修改,并自动刷新显示修改后的结果,其实Webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建,可以实现你想要的这些功能,不过它是一个单独的组件,在webpack中进行配置之前需要单独安装它作为项目依赖
npm install webpack-dev-server --save-dev
module.exports = {
devtool: 'eval-source-map',
entry: __dirname + "/src/main.js",
output: {
path: __dirname + "/public",
filename: "bundle.js"
},
devServer: {
contentBase: "./public",//本地服务器所加载的页面所在的目录
historyApiFallback: true,//不跳转
// inline: true, //实时刷新
// open:true,//自动打开浏览器
// hot:true //热替换属性
}
}
在package.json中的scripts对象中添加如下命令,用以开启本地服务器:
"scripts": {
"dev": "webpack-dev-server --open --inline --hot --config ./webpack.config.js",
//和webpack.config.js里面的devServer配置,二者有一个即可
},
Loader
通过使用不同的loader,webpack有能力调用外部的脚本或工具,实现对不同格式的文件的处理,比如说分析转换scss为css,或者把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件,对React的开发而言,合适的Loaders可以把React的中用到的JSX文件转换为JS文件。
Loaders需要单独安装并且需要在webpack.config.js中的modules关键字下进行配置,Loaders的配置包括以下几方面:
- test:一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)
- loader:loader的名称(必须)
- include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
- query:为loaders提供额外的设置选项(可选)
常用的loaders:(版本号可以自己选择,最好在当前目录安装webpack,不然会有报错)
- “babel-core”: “^6.26.3”,
- “babel-loader”: “^7.1.5”,
- “babel-plugin-transform-runtime”: “^6.23.0”,
- “babel-preset-env”: “^1.7.0”,
- “css-loader”: “^1.0.1”,
- “file-loader”: “^2.0.0”,
- “less-loader”: “^4.1.0”,
- “less”: “^3.9.0”,
- “style-loader”: “^0.23.1”,
- “url-loader”: “^1.1.2”,
在webpack.config.js里面添加
//生命模块,
//包含着各个loader
module: {
loaders: [
//webpack后面版本可以叫做roles
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.(jpg|png|gif|svg)$/,
loader: 'url-loader?limit=9510'
//如果图片大于这个limit会在导出文件夹新建个图片
},
{
test: /\.less$/,
loader: 'style-loader!css-loader!less-loader'
},
//处理ES6,7,8
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,//不包括这个目录
options: {
presets: ['env'], //处理关键词
plugins: ['transform-runtime'], //处理函数
}
}
]
},
插件(Plugins)
插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。
Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less…),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。
Webpack有很多内置插件,同时也有很多第三方插件,可以让我们完成更加丰富的功能。
Plugin举例:HtmlWebpackPlugin
这个插件的作用是依据一个简单的index.html模板,生成一个自动引用你打包后的JS文件的新index.html。这在每次生成的js文件名称不同时非常有用(比如添加了hash值)。
npm install html-webpack-plugin --save-dev
在webpack.config.js头部加上
const HtmlWebpackPlugin = require('html-webpack-plugin');
在webpack.config.js底部加上
plugins: [
new HtmlWebpackPlugin({
new HtmlWebpackPlugin({
template: __dirname + '/src/index.html', //参照物
filename:'./index_dev.html' //生成自带导入bundle.js的html文件,在public文件夹,和bundle.j一个文件夹
})
]