用webpack打包老网站(jquery切图)或重构浅谈!

随着前端技术的快速发展,前端技术栈也越来越复杂多样了。什么是webpack?他能干些啥?

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法

  • 模块化,让我们可以把复杂的程序细化为小的文件;
  • 类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能转换为JavaScript文件使浏览器可以识别;
  • Scss,less等CSS预处理器

这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常繁琐的,这就为WebPack类的工具的出现提供了需求。

很多框架都整合了webpack去打包发布项目,目前熟悉的就是用vue全家桶+webpack打包一个项目。最近两天,因工作空闲,倒腾了下用webpack去打包之前用jquery切的老网站。详情如下:

1、安装吊炸天的Node.js和npm(Node.js的包管理工具),安装完成后在命令行输入node -v 和 npm -v查看对应的版本号,则说明安装成功。

2、新建一个文件夹whitegold,利用npm或cnpm安装webpack

//先全局安装
npm install -g webpack
//安装到你的项目目录
npm install --save-dev webpack

3、安装完成后,在whitegold目录已经生成了一个node_modules的文件夹,里面都是webpack依赖包。然后创建package.json文件,这是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等等。执行命令npm init,输入这个命令后,终端会问你一系列诸如项目名称,项目描述,作者等信息,不过不用担心,如果你不准备在npm中发布你的模块,这些问题的答案都不重要,回车默认即可。

4、在文件夹内新建src文件夹, 在src下新建子文件夹css、img、js、view文件夹,在css目录下新建common、lib、page文件夹,在js目录下新建common、page文件夹,最终的目录结构如下

5、在lib文件夹新建reset.css,在page目录下新建style.less公共样式。在js下的page目录下新建index.js,article.js,list.js三个js文件,在view目录下新建index.html, list.html, article.html三个静态页面。里面可以写一些测试代码。因为博主把其三个html文件的公共头部和底部提取出来,所以目录结构如下:

6、创建webpack.config.js配置文件,这个配置文件其实也是一个简单的JavaScript模块,我们可以把所有的与打包相关的信息放在里面。我们在其中写入如下所示的简单配置代码,目前的配置主要涉及到的内容是入口文件路径和打包后文件的存放路径。基本的配置内容如下:

var path = require(‘path’);
var webpack = require(‘webpack’);
var autoprefixer = require(‘autoprefixer’);
var HtmlWebpackPlugin = require(‘html-webpack-plugin’);
var ExtractTextPlugin = require(‘extract-text-webpack-plugin’);
module.exports = {
entry: { //配置入口文件,有几个写几个
index: ‘./src/js/page/index.js’,
list: ‘./src/js/page/list.js’,
article: ‘./src/js/page/article.js’,
},
output: {
path: path.join(__dirname, ‘public’), //输出目录的配置,模板、样式、脚本、图片等资源的路径配置都相对于它
publicPath: ‘/public/’, //模板、样式、脚本、图片等资源对应的server上的路径
filename: ‘js/[name].js’, //每个页面对应的主js的生成配置
chunkFilename: ‘js/[id].chunk.js’ //chunk生成的配置
},
devServer: {
contentBase: ‘./’,
host: ‘localhost’,
port: 9090, //默认8080
inline: true, //可以监控js变化
historyApiFallback: true,//不跳转
hot: true //热启动
},
module: {
loaders:[
{
test: /\.js$/,
loader: ‘babel-loader?presets=es2015’
},{
test: /\.css$/,
use: ExtractTextPlugin.extract({ fallback: “style-loader”, use: [“css-loader”] })
},{
test: /\.less/,
use: ExtractTextPlugin.extract({ fallback: “style-loader”, use: [“css-loader”, “autoprefixer-loader”, “less-loader”] })
},{
//html模板加载器,可以处理引用的静态资源,默认配置参数attrs=img:src,处理图片的src引用的资源
//比如你配置,attrs=img:src img:data-src就可以一并处理data-src引用的资源了,就像下面这样
test: /\.html$/,
loader: “html-loader?attrs=img:src img:data-src”
},{
//文件加载器,处理文件静态资源
test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: ‘file-loader?name=./fonts/[name].[ext]’
},{
//图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求
//如下配置,将小于8192byte(8KB)的图片转成base64码
test: /\.(png|jpg|gif)$/,
loader: ‘url-loader?limit=8192&name=./img/[hash:5].[ext]’
}
]
},
externals: { // 遇到require这些时, 不需要再编译. 适合那些常用的库, 已经在页面通过<script>引入了, 就无需都打包到一起了
jquery: ‘jQuery’,
},
plugins: [
// new webpack.ProvidePlugin({ //加载jq
// $: ‘jquery’,
// jQuery: ‘jquery’
// }),
newwebpack.optimize.CommonsChunkPlugin({
name: ‘ymsj’, // 将公共模块提取,生成名为`ymsj`的chunk
chunks: ‘all’, //提取哪些模块共有的部分
minChunks: 3 // 提取至少3个模块共有的部分
}),
newExtractTextPlugin(‘css/[name].css’),//单独使用link标签加载css并设置路径,相对于output配置中的publickPath
newHtmlWebpackPlugin({//根据模板插入css/js等生成最终HTML
favicon: ‘./src/img/favicon.ico’, //favicon路径,通过webpack引入同时可以生成hash值
filename: ‘./view/index.html’, //生成的html存放路径,相对于path
template: ‘./src/view/index.html’, //html模板路径
inject: ‘body’, //js插入的位置,true/’head’/’body’/false
hash: true, //为静态资源生成hash值
chunks: [‘ymsj’, ‘index’],//需要引入的chunk,不配置就会引入所有页面的资源
minify: { //压缩HTML文件
removeComments: false, //移除HTML中的注释
collapseWhitespace: false //删除空白符与换行符
}
}),
newHtmlWebpackPlugin({//根据模板插入css/js等生成最终HTML
favicon: ‘./src/img/favicon.ico’, //favicon路径,通过webpack引入同时可以生成hash值
filename: ‘./view/list.html’, //生成的html存放路径,相对于path
template: ‘./src/view/list.html’, //html模板路径
inject: true, //js插入的位置,true/’head’/’body’/false
hash: true, //为静态资源生成hash值
chunks: [‘ymsj’, ‘list’],//需要引入的chunk,不配置就会引入所有页面的资源
minify: { //压缩HTML文件
removeComments: true, //移除HTML中的注释
collapseWhitespace: false //删除空白符与换行符
}
}),
newHtmlWebpackPlugin({//根据模板插入css/js等生成最终HTML
favicon: ‘./src/img/favicon.ico’, //favicon路径,通过webpack引入同时可以生成hash值
filename: ‘./view/article.html’, //生成的html存放路径,相对于path
template: ‘./src/view/article.html’, //html模板路径
inject: true, //js插入的位置,true/’head’/’body’/false
hash: true, //为静态资源生成hash值
chunks: [‘ymsj’, ‘article’],//需要引入的chunk,不配置就会引入所有页面的资源
minify: { //压缩HTML文件
removeComments: true, //移除HTML中的注释
collapseWhitespace: false //删除空白符与换行符
}
}),
newwebpack.BannerPlugin(‘白山羊案例V2.0.0 2017-9 Wginit ‘),
newwebpack.optimize.OccurrenceOrderPlugin(),
newwebpack.optimize.UglifyJsPlugin(),
newwebpack.HotModuleReplacementPlugin()//热加载
],
};
注意上面的loaders写法,因为随着webpack版本不断变化,某些写法上也有很大的不同,本文用的是less-loader来编译less,用autoprefixer来补充兼容前缀,特别注意下面的写法!!

6、详细配置package.json文件,安装页面渲染等各种loaders,package.json内容如下:

{
“name”: “test”,
“version”: “2.0.0”,
“description”: “白山羊webpack打包案例”,
“main”: “index.js”,
“dependencies”: {
“autoprefixer-loader”: “^3.2.0”,
“autoprefixer”: “^7.1.3”,
“babel-core”: “^6.26.0”,
“babel-loader”: “^7.1.2”,
“babel-preset-es2015”: “^6.24.1”,
“babel-preset-stage-0”: “^6.24.1”,
“css-loader”: “^0.28.7”,
“extract-text-webpack-plugin”: “^3.0.0”,
“file-loader”: “^0.11.2”,
“html-loader”: “^0.5.1”,
“html-webpack-plugin”: “^2.30.1”,
“less”: “^2.7.2”,
“less-loader”: “^4.0.5”,
“postcss-loader”: “^2.0.6”,
“style-loader”: “^0.18.2”,
“url-loader”: “^0.5.9”,
“webpack”: “^3.5.5”,
“webpack-dev-server”: “^2.7.1”,
“jquery”: “1.11.1”
},
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″,
“start”: “webpack”,
“server”: “webpack-dev-server –open”
},
“author”: “Wginit”,
“license”: “ISC”,
“devDependencies”: {
“copy-webpack-plugin”: “^4.0.1”,
“html-webpack-plugin”: “^2.30.1”
}
}

配置完成后,在命令行输入webpack或者npm start (因为在package.json中的scripts下已经定义)

ok,出现以上目录结构可说明打包成功!打开根目录whitegold文件夹,发现当中已新生成了一个public文件夹,对的,此文件夹就是打包后的静态资源文件夹,之后打包发布的就是它了。图片文件名都以其hash值前五位来命名,对低于8k的图片都转base64来减少http请求。
7、打包完成后,执行npm run server,如下图所示:
ok,执行没错误后,node服务器会在浏览器中自动打开网页,并以我们自定义的9090端口监听,完成后的3个页面如下:
     
检查元素可以看到已打包的静态文件都已插入到对应的html页面中。
结尾:再次强调下,webpack打包支持环境IE9+(想兼容ie7、8的就别来试了,虽说有插件可以去弄(可以参考https://github.com/zuojj/fedlab/issues/5),但坑超级多,耗不起,还是老老实实的用jq切图吧~!),已上,欢迎各路大牛拍砖矫正。