我的webpack使用
webpack作为模块打包机,在前端模块化开发中频繁的被使用。本篇主要记录一些我自己在学习和使用webpack中遇到问题,保存的一些比较好的博客文章和自己项目的webpack的配置文档,方便以后项目中使用时参考,不用每次都去翻老项目看webpack配置,有些第三方loader和插件的配置或者名称有时就是想不起来(看来老了呀)。
如果想学习webpack的相关内容可以从下面第一小节关于webpack的一些资源bolg中查看一些网上的教程,如果你对gulp和webpack有疑问,想了解他们的区别也可以看一下这篇Gulp和Webpack对比
关于webpack的一些资源bolg
- 入门Webpack,看这篇就够了
- Webpack 中文指南
- Webpack课件
- Webpack学习总结
- Webpack学习总结 另一份
- webpack在PC项目中的应用
- 图片的路径与打包
- webpack 教程资源收集(包括与Vue,与React,与Angular项目使用)
- 阮一峰老师的webpack-demos
上面这些关于webpack的资源已经可以满足你对webpack的学习了,其中每篇Bolg各有千秋,都有自己侧重点,值得好好学习。
webpack配置文件
单独使用
所谓的单独使用就是在项目开发过程中,直接通过webpack
或者webpack server
来使用webpack的相关功能。与之相对的是通过nodeJS来配合使用webpack,下一小节介绍。
当我单独使用webpack时,我的配置文件就一个webpack.config.js
,简单配置,可根据不通项目添加loader和plugins。
var Webpack = require('webpack');
var Et = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
entry: [ __dirname + "/src/scripts/app.js"],//唯一入口文件,可以是对象或者数组
output: {
path: __dirname + "/prd/",//打包后的文件存放的地方
//filename: "[name]-[hash].js"//打包后输出文件的文件名并且版本控制,一般不用与生产环境中
filename: "bundle.js"//打包后输出文件的文件名
},
module:{
loaders:[
{
test:/\.css$/,
loader:'style!css'
},
{
test: /\.scss$/,
loader: Et.extract('style','css!sass')//从js中抽离scss文件
// loader:'style!css!sass'
},
{
test:/\.js$/,
exclude: /node_modules/,//屏蔽不需要处理的文件(文件夹)(可选)
loader:'babel'
},
{
test:/\.string$/,
loader:'string'
},
// {
// test: /\.html$/,
// loader: 'html-withimg-loader'
// },
{
test: /\.(png|jpg|jpeg|gif)$/,
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'//图片打包限制,这个限制并不是说超过了就不能打包,而是指当图片大小小于限制时会自动转成 base64 码引用。上例中大于8192字节的图片正常打包,小于8192字节的图片以 base64 的方式引用。
}
]
},
plugins: [
//复制文件
new CopyWebpackPlugin([
{
from : './src/images',//定义要拷贝的源目录 __dirname + ‘/src/public’
to : './images',//定义要拷贝的目标目录 __dirname + ‘/dist’
// toType : 'dir'//file 或者 dir , 可选,默认是文件
// force : 强制覆盖先前的插件 , 可选 默认false
// context : 不知道作用 , 可选 默认 base context 可用 specific context
// flatten :只拷贝文件不管文件夹 , 默认是false
// ignore : 忽略拷贝指定的文件 ,可以用模糊匹配
},{
from : './index.html',//定义要拷贝的源目录 __dirname + ‘/src/public’
}
]),
//自动打开浏览器
new OpenBrowserPlugin({url: 'http://localhost:80/' + 'index.html'}),
//js文件压缩
//new Webpack.optimize.UglifyJsPlugin(),
//从js中抽离scss文件并且版本控制
//new Et('[name]-[hash].css')
new Et('bundle.css'),//从js中抽离scss文件
//html文件操作
// new HtmlWebpackPlugin({
// template: './prd/index.html',
// })
],
devServer: {
contentBase: __dirname + '/prd',//本地服务器所加载的页面所在的目录
port:8080,
colors: true,//终端中输出结果为彩色
//historyApiFallback: true,//不跳转
inline: true,//实时刷新
hot: true//热启动
}
}
以上配置不代表任何含义,只是一个有助于自己以后方便查找的文档而已。
通过NodeJS使用
此时需要一个另外配置server.js,通过node运行server.js来加载配置文件。
server.js
var webpack = require('webpack');
var webpackeDevServer = require('webpack-dev-server');
var config = require('./webpack.config.js');//webpack配置文件路径
new webpackeDevServer(webpack(config),{
contentBase: __dirname + '/prd',//本地服务器所加载的页面所在的目录
port:80,
colors: true,//终端中输出结果为彩色
quiet: false, //控制台中不输出打包的信息
historyApiFallback: true,//不跳转
inline: true,//实时刷新
hot: true,//热启动
progress: true, //显示打包的进度
lazy: false,//懒加载
//反向代理
proxy:{
'/http://chping.site/*':{
target:'http:localhost:3000',
pathRewrite: {
'^/http://chping.site/':''
}
}
}
}).listen(80,'localhost',function(err,result){
if(err){
console.log(err);
}else{
console.log('listening at localhost:80');
}
});
webpack.config.js
var Webpack = require('webpack');
var Et = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
entry: [
//react-hot配置
'webpack-dev-server/client?http://localhost',
'webpack/hot/only-dev-server',
__dirname + "/src/scripts/app.js",
],//已多次提及的唯一入口文件
output: {
path: __dirname + "/prd/",//打包后的文件存放的地方
//filename: "[name]-[hash].js"//打包后输出文件的文件名并且版本控制
filename: "bundle.js"//打包后输出文件的文件名
},
module:{
loaders:[
{
test:/\.css$/,
loader:'style!css'
},
{
test: /\.scss$/,
loader: Et.extract('style','css!sass')//从js中抽离scss文件
// loader:'style!css!sass'
},
{
test:/\.js$/,
exclude: /node_modules/,//屏蔽不需要处理的文件(文件夹)(可选)
loader:'babel'
},
{
test:/\.string$/,
loader:'string'
},
// {
// test: /\.html$/,
// loader: 'html-withimg-loader'
// },
{
test: /\.(png|jpg|jpeg|gif)$/,
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'//图片打包限制,这个限制并不是说超过了就不能打包,而是指当图片大小小于限制时会自动转成 base64 码引用。上例中大于8192字节的图片正常打包,小于8192字节的图片以 base64 的方式引用。
}
]
},
plugins: [
//plugin热启动
new Webpack.HotModuleReplacementPlugin(),
//复制文件
new CopyWebpackPlugin([
{
from : './src/images',//定义要拷贝的源目录 __dirname + ‘/src/public’
to : './images',//定义要拷贝的目标目录 __dirname + ‘/dist’
// toType : 'dir'//file 或者 dir , 可选,默认是文件
// force : 强制覆盖先前的插件 , 可选 默认false
// context : 不知道作用 , 可选 默认 base context 可用 specific context
// flatten :只拷贝文件不管文件夹 , 默认是false
// ignore : 忽略拷贝指定的文件 ,可以用模糊匹配
},{
from : './index.html',//定义要拷贝的源目录 __dirname + ‘/src/public’
}
]),
//自动打开浏览器
new OpenBrowserPlugin({url: 'http://localhost:80/' + 'index.html'}),
//js文件压缩
//new Webpack.optimize.UglifyJsPlugin(),
//从js中抽离scss文件并且版本控制
//new Et('[name]-[hash].css')
new Et('bundle.css'),//从js中抽离scss文件
//html文件操作
// new HtmlWebpackPlugin({
// template: './prd/index.html',
// })
]
}
相比较单独使用的webpack配置文件,此处的webpack.config.js
文件中取消了dev-server的配置,并且在入口entry中添加了部分设置和在plugins中添加了热启动的相关配置。
React中使用
React开发中使用webpack是件很美妙的事情,这里有篇文章可以了解一下深入浅出React(二):React开发神器Webpack,热更新是个很方便使用的技能,用webpack实现其实也不难,只需要安装一个react-hot-loader,然后简单配置一下就好了。下面是webpack的相关配置:
server.js文件同上一小节总NodeJS中一致,下面是webpack.config.js的配置,重点注意入口文件配置项和plugins配置。
var webpack = require('webpack');
var ET = require('extract-text-webpack-plugin');
module.exports = {
// 入口
entry: [
'webpack-dev-server/client?http://localhost',
'webpack/hot/only-dev-server',
__dirname + '/src/scripts/app.js'
],
// 出口
output: {
path: __dirname + '/prd',
// filename: '[name]-[hash].js'
filename: 'bundle.js'
},
// sourcemap
devtool: 'source-map',
// 配置模块
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modues/,
loader: 'babel'
},
{
test: /\.jsx$/,
exclude: /node_modues/,
loader: 'babel'
},
{
test: /\.css$/,
loader: 'style!css'
},
{
test: /\.scss$/,
loader: ET.extract('style', 'css!sass')
}
]
},
//plugins定义
plugins: [
// new webpack.optimize.UglifyJsPlugin(),
new ET('bundle.css', {
allChunks: true
}),
new webpack.HotModuleReplacementPlugin()
]
}
另外除了webpack.config.js文件的配置外,在react的入口文件(或者说使用react-dom的文件中)添加三行语句:
'use strict';
import '../styles/usage/page/app.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import MyButtonController from './flux/components/MyButtonController.jsx';
let app = document.getElementById('app');
ReactDOM.render(
<MyButtonController />
, app);
//热更新三行语句
if (module.hot) {
module.hot.accept();
}
这样就可以开发react时使用热更新了。
常用插件和loader
css-loader: css文件加载
sass-loader: scss文件加载
less-loader: less文件加载
extract-text-webpack-plgin: css文件抽离插件
html-loader: html文件加载
html-webpack-plugin: 创建默认html文件插件
js-loader: js文件加载
string-loader: string文件加载
url-loader: 图片加载打包
vue-loader: vue文件加载
jsx-loader: jsx文件加载/js文件也可以
react-hot-loader: react热更新
open-browser-webpack-plgin: 自动打开浏览器插件
copy-webpack-plgin: 文件复制插件
webpack-dev-server: 本地server服务
更多loader请参照官方文档
小结
以后就可以不用翻老项目找配置文件了。。。