使用NPM + Webpack进行前端开发的示例
来源:互联网 发布:mac os 10.12 原版 编辑:程序博客网 时间:2024/06/06 00:29
最近在使用Webpack来帮助进行前端开发,觉得这个东西的确挺好用。所以用一个简单的示例记录一下,供他人以及自己以后的参考。
这篇文章不是Webpack的教程贴,也不分析Webpack的优缺点,只是简单的记录我自己觉得还不错的一套用法,在阅读本文前,读者需要对NPM以及Webpack有个基础的了解。
1.项目结构
项目名称叫webpack-demo。
源代码目录是app,下面有三个文件夹,js,less(当然你也可以使用postcss或者sass等),以及html。
package.json是npm中的包管理配置文件,webpack.config.js是webpack默认的配置文件,webpack.plugin.js则是我为了使webpack.config.js看起来更清晰而提取出的一些配置内容,顾名思义是提取出了插件的配置。
node_modules是执行npm install后依赖包的安装目录。
build文件夹则是最终项目编译后的结果,其中的JS和CSS是webpack根据源代码中的依赖自动生成的一个个bundle文件,而html则是原封不动的从app中复制过去的。
二、配置分析
1.package.json
{ "name": "webpack-demo", "version": "1.0.0", "description": "", "scripts": { "product": "webpack", "dev": "webpack" }, "dependencies": { "jquery": "^3.1.0" }, "devDependencies": { "clean-webpack-plugin": "^0.1.10", "copy-webpack-plugin": "^3.0.1", "css-loader": "^0.23.1", "extract-text-webpack-plugin": "^1.0.1", "less": "^2.7.1", "less-loader": "^2.2.3", "style-loader": "^0.13.1", "webpack": "^1.13.1", "webpack-merge": "^0.14.1" }}
这里面主要的就是scripts和两个dependencies。之所以要分product和dev两个script,是用来区分生产和开发两种环境,这关系到webpack中的配置。
两个dependencies的内容就是开发和运行时所依赖的包,对这两个东西不太清楚的读者可以参考stackoverflow上的回答。
2.webpack配置
webpack.config.js
/** * Created by hshen on 8/15/16. */// Define pathsconst path = require('path');const PATHS = { app: path.join(__dirname, 'app'), build: path.join(__dirname, 'build')};// A tool to merge config objectconst merge = require('webpack-merge');// Configuration for pluginsconst plugins = require('./webpack.plugins');// Common configuration for production and devconst common = merge( { entry: { page_a: path.join(PATHS.app,'js','pages','page_a.js'), page_b: path.join(PATHS.app,'js','pages','page_b.js') }, output: { path: path.join(PATHS.build,'js'), filename: '[name].js', chunkFilename: '[chunkhash].js' }, resolve: { root: [ PATHS.app ], alias: { js: 'js', css: 'less' }, extensions: ['', '.js'] } }, plugins.clean(PATHS.build), plugins.copy(), plugins.extractCommon('common.js'), plugins.less());var config = null;// Detect the branch where npm is running onswitch(process.env.npm_lifecycle_event) { case 'product': config = merge( common, plugins.minify() ); break; case 'dev': default: config = merge( common, // Set source map for debug { devtool: 'source-map' } ); break;}module.exports = config;
根据注释大概可以知道配置是怎么工作的:
dev和product打包都需要的操作: 对每个页面的入口文件及其依赖打包成一个bundle;对路径做一些alias,方便js中的依赖;提取各个页面的公共依赖作为common;复制html;编译less。(当然还可以加上jshint等更多的功能)
对于dev,加上sourcemap用于debug;对于product,做minify的处理。
为了使配置结构更清晰,我提取了插件配置的部分到单独的webpack.plugins.js中。
webpack.plugins.js
/** * Created by hshen on 8/15/16. */const webpack = require('webpack');exports.minify = function () { return { plugins: [ new webpack.optimize.UglifyJsPlugin({ // Don't beautify output (enable for neater output) beautify: false, // Eliminate comments comments: false, compress: { warnings: false, // Drop `console` statements drop_console: true } }) ] };}// Clean a specific folderexports.clean = function (path) { const CleanWebpackPlugin = require('clean-webpack-plugin'); return { plugins: [ new CleanWebpackPlugin([path], { // Without `root` CleanWebpackPlugin won't point to our // project and will fail to work. root: process.cwd() }) ] };}exports.extractCommon = function (name) { return { plugins: [ new webpack.optimize.CommonsChunkPlugin(name) ] };}exports.copy = function () { const path = require('path'); const PATHS = { app: path.join(__dirname, 'app'), build: path.join(__dirname, 'build') }; const CopyWebpackPlugin = require('copy-webpack-plugin'); return { plugins: [ new CopyWebpackPlugin([ { from: path.join(PATHS.app,'html'), to: path.join(PATHS.build,'html')}, ], { ignore: [ ], // By default, we only copy modified files during // a watch or webpack-dev-server build. Setting this // to `true` copies all files. copyUnmodified: true }) ] };}exports.less = function () { var ExtractTextPlugin = require("extract-text-webpack-plugin"); var extractLESS = new ExtractTextPlugin('../css/[name].css',{allChunks: true}); return { module: { loaders: [ { test: /\.less$/, exclude: /node_modules/, loader: extractLESS.extract("style-loader", "css-loader!less-loader") } ] }, plugins: [ extractLESS ] };};
三、源文件分析
a.html
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>Webpack demo a</title> <link href="../css/page_a.css" rel="stylesheet" type="text/css"></head><body><script type="text/javascript" src="../js/common.js"></script><script type="text/javascript" src="../js/page_a.js"></script></body></html>
对于所有的html而言,都只需要通用的common.js以及每个页面自己单独的page_x.js。
因为html是直接被复制过去的,所以这里引的css和js都是编译和打包之后的(当然,如果对性能要求不高,可以直接用less-loader而不用extract-text插件,这样的话css就会直接内嵌到js中)。
page_a.js
/** * Created by hshen on 8/15/16. */var $ = require('jquery');var component = require('js/components/ComponentA');require('css/page_a.less');$('body').append(component);
为了不让css内嵌在js中,使浏览器可以平行加载js和css,从而提高性能,我使用了extract-text插件。
用extract-text插件的一个坏处: 我除了在html中手动去引css,还要在js中去引编译前的less。这样很不利于代码的维护。如果有读者知道怎么解决这个问题,请不吝赐教!
四、为什么不一起使用Bower、Grunt等
对于包管理,我觉得NPM一个就足够了,再额外使用Bower有点多此一举,另外还增加了配置的复杂度。
对于Grunt等Task Runner,Webpack本身已经有足够多的插件可以让我们去做很多事情,再把Grunt加上去也会增加复杂度。对于插件没有提供的东西,其实自己写点NPM的script也是可以解决的。
当然我也很期待读者能够给我不一样的看法!
1 0
- 使用NPM + Webpack进行前端开发的示例
- 前端开发工具--webpack的使用
- 【webpack】使用webpack进行ES6开发
- CentOS7下使用CNPM进行NPM、WEBPACK打包
- 使用webpack 进行ES6开发
- 使用npm+gulp+browserify网页前端开发
- 使用Gulp + Webpack定制前端开发环境
- 使用webpack+npm多元化命令
- 使用 Webpack 和 ES6 进行 React 开发
- 前端学习笔记-webpack的使用
- 使用vue做前端开发时涉及到npm的一些常用指令
- 使用chrome进行前端开发
- 使用 webpack + react + redux + es6 开发组件化前端项目
- 使用 webpack + react + redux + es6 开发组件化前端项目
- 使用 webpack + react + redux + es6 开发组件化前端项目
- 使用 webpack + react + redux + es6 开发组件化前端项目
- 使用 webpack + react + redux + es6 开发组件化前端项目
- npm Webpack
- 简单的mvp+retrofit+rxjava示例
- 适配器模式
- http://blog.csdn.net/evankaka/article/details/48785513
- python将文件读取为字符串
- 树(Persistent Bookcase,cf 707d)
- 使用NPM + Webpack进行前端开发的示例
- SpringMVC中利用字符集过滤器characterEncodingFilter解决中文乱码
- 用java写的一个排序算法
- CountDownLatch应用
- C++ Socket编程步骤
- Codeforces Round #368 (Div. 2) D. Persistent Bookcase(n层m个的书架的四种操作)
- 设计模式C++版:第五式装饰者模式
- Oracle报错宗介
- cf#348-E. Little Artem and Time Machine-树状数组+map节点(动态开点树状数组)