基于webpack搭建前端工程的思考

蚊子前端博客
发布于 2017-10-13 20:03
webpack是一个前端打包构建工具, 功能强大,本篇也是基于webpack简单探讨下前端的工程化

前端工程化的概念和思想早就已讨论过,并且之前也用 requireJS 和 seaJS 实现过,同时,在 2015 年,ECMAscript 也发布了 js 的正式版 ES6。在 ES6(ES2015)中,实现了标准上的统一,从底层上实现了模块化的支持。不过由于浏览器发展的滞后性,尤其是 IE,ES6 中很多的属性依然是不支持的,因此也就出现了第三方工具babel,将 ES6 语法转换为浏览器统一支持的 ES5。

在上一篇文章中,我们对 webpack 也有个简单的了解了,在 webpack 中,一切皆资源,CSS,JS,图片等都可以作为资源处理。将资源进行分类,模块化的管理,适配到不同的页面。

1. 资源管理

项目的工程化,最主要的就是对资源的管理,对整个项目进行思考后,如何拆分资源。对于业务上的组件,我们可以放到components的目录中,然后对外暴露接口。

webpack 对 CommonJS,AMD 和 ES6 的模块化都有非常好的支持,不过我们最好还是安装 ES6 的标准来写代码。webpack 编译打包后,都会打包到一个文件中。同时,webpack 让我们更加专注逻辑代码的编写,而不用关心代码是如何被引用的。

关于exportimport具体如何使用,可以参考阮一峰的文章 Module 的语法

2. 本地开发环境

一个项目的目录结构可以是这样的:

COPYTEXT

`-out # 编译后 `-src # 原文件 `---css `---img `---js `---components # 组件 `-entry.js `-package.json `-webpack.config.js # 配置文件 `-index.html

为了方便本地的开发和调试,我们使用webpack-dev-server搭建一个本地服务:

COPYBASH

npm install webpack-dev-server --save-dev

下载安装完成后,我这里对应的版本号是:

COPYJSON

{ "webpack": "^2.7.0", "webpack-dev-server": "^2.9.1" }

本来安装网上的教程配置 server 时,各种出错,后来就一点点注释,看看是哪里配置错了,结果只能把整个devServer的配置全部注释掉。

启动服务:

COPYBASH

webpack-dev-server --open -hot

程序会自动打开浏览器http://localhost:8080。但是,这里有个问题,页面该怎么引入静态资源呢,其实静态资源的路径就是在 webpack.config.js 中的output中配置的:

COPYJAVASCRIPT

output : { publicPath: '/dist/', filename: '[name].js' }

那么 src 中的静态资源就会编译到 /dist/ 的路径中了,页面中直接引用就行了。不过,当我们查看项目目录时,却没有 dist 目录,其实在使用webpack-dev-server启动本地服务后,编译的 /dist/ 目录是只存在在内存中的,服务关闭后,dist 目录就不存在了。

3. webpack 的配置

在之前的文章中,我们把 webpack 的配置写到了webpack.config.js中。编译时,默认就是调用该文件中的配置。但是,从代码开发到部署到线上,要经历 3 个环境: 本地开发环境、测试环境与正式环境。

不过我们这里,只配置本地开发环境和测试环境,正式环境与测试环境的代码已经一样了,只是正式环境是另一套发布流程了:

  • webpack.base.config.js 基础配置

  • webpack.dev.config.js 本地开发环境

  • webpack.pro.config.js 测试环境

webpack.base.config.js :

COPYJAVASCRIPT

var webpack = require('webpack'), path = require('path'), ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: function () { return { index: './src/index.js', }; }, output: { publicPath: '/dist/', filename: '[name].js', }, // 新添加的module属性 module: { rules: [ { test: /\.js?$/, loader: 'babel-loader', exclude: /(node_modules|bower_components)/, options: { presets: ['es2015'], }, }, { test: /\.css$/, // loader: "style!css" use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader', }), }, { test: /\.(jpg|png)$/, loader: 'url?limit=8192', }, { test: /\.scss$/, // loader: "style!css!sass" use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!sass-loader', }), }, ], }, plugins: [], };

webpack.dev.config.js :

COPYJAVASCRIPT

const base = require('./webpack.base.config'), ExtractTextPlugin = require('extract-text-webpack-plugin'); const config = Object.assign({}, base, { output: { publicPath: '/dist/', filename: '[name].js', }, plugins: [new ExtractTextPlugin({ filename: '[name].css', disable: false, allChunks: true })], }); module.exports = config;

webpack.pro.config.js :

COPYJAVASCRIPT

const base = require('./webpack.base.config'), ExtractTextPlugin = require('extract-text-webpack-plugin'); const config = Object.assign({}, base, { output: { publicPath: './build/', filename: '[name]-[chunkhash:8].js', }, plugins: [ new ExtractTextPlugin({ filename: '[name].css', disable: false, allChunks: true }), new webpack.BannerPlugin('created at ' + new Date().toLocaleString()), ], }); module.exports = config;

webpack.base.config.js 是基础文件,不直接调用,我们在 package.json 中把命令简化一下:

COPYJSON

"scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot --config config/webpack.dev.config.js", "build": "cross-env NODE_ENV=production webpack --progress --hide-modules --config config/webpack.pro.config.js" }

运行npm run dev命令时,调用的是 webpack.dev.config.js,进行本地开发;运行npm run build,调用 webpack.pro.config.js,进行预发布编译。

4. 总结

因为项目的难易程度,部署代码、测试发布的流程都不一样,在 webpack 的开发过程中,也依然需要遵循公司的标准进行自动化的整合。

标签:
阅读(633)

公众号:

qrcode

微信公众号:前端小茶馆

相关文章

公众号:

qrcode

微信公众号:前端小茶馆