├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── README.md ├── package.json ├── src ├── css │ ├── common │ │ ├── global.css │ │ └── grid.css │ ├── lib │ │ └── reset.css │ └── page │ │ ├── about.less │ │ ├── index.less │ │ └── list.less ├── img │ ├── 4.png │ ├── favicon.ico │ └── mask.png ├── js │ ├── components │ │ └── dialog │ │ │ ├── css │ │ │ └── dialog.css │ │ │ ├── img │ │ │ └── 1.png │ │ │ ├── index.js │ │ │ └── tmpl │ │ │ └── dialog.html │ └── page │ │ ├── about.js │ │ ├── index.js │ │ └── list.js └── view │ ├── about.html │ ├── index.html │ └── list.html └── webpack.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | extends: 'standard', 8 | // required to lint *.vue files 9 | plugins: [ 10 | 'html' 11 | ], 12 | // add your custom rules here 13 | rules: { 14 | 'no-new': 'off' 15 | }, 16 | globals: {} 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 基于webpack的前端工程化开发之多页站点篇(一) 2 | 3 | **声明:此文只作为webpack入门学习交流,不作为实际项目参考(基于webpack1.x)。** 4 | 5 | 在最初接触webpack的较长一段时间里,我(也可能很多人)都觉得webpack是专为单页应用而量身打造的,比如webpack+react、webpack+vue等,都可以近乎完美的解决各种资源的依赖加载、打包的问题。甚至css都是打包在js里去动态添加到dom文档中去。 6 | 7 | 后来想想,这么好的工具这么好的方案为什么不能用在website(普通的web站点,姑且叫做website吧)中呢? 8 | 9 | - 首先对于普通的web站点,我们更倾向于将css独立出来,因为对于website来说,css还是要最先加载出来比较好。 10 | 11 | - 再然后js我们也只想加载需要的部分,而不是一个大大的打包了所有js模块的包。 12 | 13 | 在很多webpack入门级的demo里,无论是单入口的还是多入口的,都没有解决上面两个问题。入门毕竟是入门,要晋级还是只能靠自己。幸运的是,有很多优秀的工程师已为我们铺好了路,让我们在前端工程化的道路上少走很多的弯路。如果你也一样曾迷茫过,请不要走开,希望这里能为你答疑解惑。 14 | 15 | 好吧,以上通通是废话,接下来上干货。 16 | 17 | --- 18 | 19 | 首先开始构建我们的项目目录结构。 20 | 21 | #### 初始化项目、安装依赖 22 | 23 | 使用`npm init`初始化项目就不多说了,生成package.json文件。 24 | 25 | 使用`npm install plugins --save-dev`安装项目所需依赖。最终package.json的依赖声明如下: 26 | 27 | ```javascript 28 | "devDependencies": { 29 | "css-loader": "^0.23.1", 30 | "extract-text-webpack-plugin": "^1.0.1", 31 | "file-loader": "^0.8.5", 32 | "html-loader": "^0.4.3", 33 | "html-webpack-plugin": "^2.9.0", 34 | "jquery": "^1.12.0", 35 | "less": "^2.6.0", 36 | "less-loader": "^2.2.2", 37 | "style-loader": "^0.13.0", 38 | "url-loader": "^0.5.7", 39 | "webpack": "^1.12.13", 40 | "webpack-dev-server": "^1.14.1" 41 | } 42 | ``` 43 | 44 | #### 主要目录结构 45 | 46 | ``` 47 | - website 48 | - src #代码开发目录 49 | - css #css目录,按照页面(模块)、通用、第三方三个级别进行组织 50 | + page 51 | + common 52 | + lib 53 | + img #图片资源 54 | - js #JS脚本,按照page、components进行组织 55 | + page 56 | + components 57 | + view #HTML模板 58 | - dist #webpack编译打包输出目录,无需建立目录可由webpack根据配置自动生成 59 | + css 60 | + js 61 | + view 62 | + node_modules #所使用的nodejs模块 63 | package.json #项目配置 64 | webpack.config.js #webpack配置 65 | README.md #项目说明 66 | ``` 67 | > 假如你是一名纯粹的前端工程师,使用webpack构建website的目录结构大概就这样了,当然你也可以根据自己的喜好自由设计目录结构。 68 | > 69 | > 详细的代码全貌可以提前在这里“窥看”——。 70 | 71 | 目录组织好,我们就可以开始撸代码了。 72 | 73 | #### 开发页面 74 | 75 | 在src/js/page目录下建立index.js文件,在src/view目录下建立index.html文件。入口js和模板文件名对应。 76 | 77 | index.js内容如下: 78 | 79 | ```javascript 80 | //引入css 81 | require("../../css/lib/reset.css") 82 | require("../../css/common/global.css") 83 | require("../../css/common/grid.css") 84 | require("../../css/page/index.less") 85 | 86 | $('.g-bd').append('

这是由js生成的一句话。

') 87 | ``` 88 | 89 | index.html 内容如下: 90 | 91 | ```xml 92 | 93 | 94 | 95 | 96 | 首页 97 | 98 | 101 | 102 | 103 |
104 |
105 | 106 |

107 | 108 |

109 |
110 |
111 | 114 | 115 | 116 | ``` 117 | 就是这样一个简单的HTML模板,我们甚至没有引入任何CSS和JS,通过webpack打包就可以自动帮我们引入。 118 | 119 | 由于是做website,在此之前相信你对单页应用打包已经有过了解,我就不客气了,再来两个页面压压惊。 120 | 121 | about.js: 122 | 123 | ```javascript 124 | //引入css 125 | require('../../css/lib/reset.css') 126 | require('../../css/common/global.css') 127 | require('../../css/common/grid.css') 128 | require('../../css/page/about.less') 129 | 130 | $('#about').html('这是一个关于webpack构建工程的栗子') 131 | ``` 132 | about.html: 133 | 134 | ```xml 135 | 136 | 137 | 138 | 139 | 关于 140 | 141 | 142 | 143 |
144 |
145 |
146 |
147 |
148 | 149 | 150 | ``` 151 | list.js: 152 | 153 | ```javascript 154 | //引入css 155 | require('../../css/lib/reset.css') 156 | require('../../css/common/global.css') 157 | require('../../css/common/grid.css') 158 | require('../../css/page/list.less') 159 | 160 | 161 | var html = '' 162 | for(var i = 0; i < 5; i++){ 163 | html += '
  • 列表' + (i + 1) + '
  • ' 164 | } 165 | 166 | $('#list').html(html); 167 | ``` 168 | 169 | list.html: 170 | 171 | ```xml 172 | 173 | 174 | 175 | 176 | 列表页 177 | 178 | 179 | 180 |
    181 |
    182 | 183 |
    184 |
    185 | 186 | 187 | ``` 188 | 189 | OK,太棒了!!! 190 | 191 | #### webpack配置 192 | 193 | 这里是关键,在webpack.config.js里,我们将进行一些配置,来完成我们的需求,一开始或许有点难理解,但等你真的掌握了,你便会惊呼它的神奇。配置中我写了详细的注释,要想彻底理解,还需多实践,多查阅文档,必要时看看源码,呜呼,学习之路漫漫兮。 194 | 195 | ```javascript 196 | var path = require('path') 197 | var webpack = require('webpack') 198 | /* 199 | extract-text-webpack-plugin插件, 200 | 有了它就可以将你的样式提取到单独的css文件里, 201 | 妈妈再也不用担心样式会被打包到js文件里了。 202 | */ 203 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 204 | /* 205 | html-webpack-plugin插件,重中之重,webpack中生成HTML的插件, 206 | 具体可以去这里查看https://www.npmjs.com/package/html-webpack-plugin 207 | */ 208 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 209 | 210 | module.exports = { 211 | entry: { //配置入口文件,有几个写几个 212 | index: './src/js/page/index.js', 213 | list: './src/js/page/list.js', 214 | about: './src/js/page/about.js', 215 | }, 216 | output: { 217 | path: path.join(__dirname, 'dist'), //输出目录的配置,模板、样式、脚本、图片等资源的路径配置都相对于它 218 | publicPath: '/dist/', //模板、样式、脚本、图片等资源对应的server上的路径 219 | filename: 'js/[name].js', //每个页面对应的主js的生成配置 220 | chunkFilename: 'js/[id].chunk.js' //chunk生成的配置 221 | }, 222 | module: { 223 | loaders: [ //加载器,关于各个加载器的参数配置,可自行搜索之。 224 | { 225 | test: /\.css$/, 226 | //配置css的抽取器、加载器。'-loader'可以省去 227 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader') 228 | }, { 229 | test: /\.less$/, 230 | //配置less的抽取器、加载器。中间!有必要解释一下, 231 | //根据从右到左的顺序依次调用less、css加载器,前一个的输出是后一个的输入 232 | //你也可以开发自己的loader哟。有关loader的写法可自行谷歌之。 233 | loader: ExtractTextPlugin.extract('css!less') 234 | }, { 235 | //html模板加载器,可以处理引用的静态资源,默认配置参数attrs=img:src,处理图片的src引用的资源 236 | //比如你配置,attrs=img:src img:data-src就可以一并处理data-src引用的资源了,就像下面这样 237 | test: /\.html$/, 238 | loader: "html?attrs=img:src img:data-src" 239 | }, { 240 | //文件加载器,处理文件静态资源 241 | test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, 242 | loader: 'file-loader?name=./fonts/[name].[ext]' 243 | }, { 244 | //图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求 245 | //如下配置,将小于8192byte的图片转成base64码 246 | test: /\.(png|jpg|gif)$/, 247 | loader: 'url-loader?limit=8192&name=./img/[hash].[ext]' 248 | } 249 | ] 250 | }, 251 | plugins: [ 252 | new webpack.ProvidePlugin({ //加载jq 253 | $: 'jquery' 254 | }), 255 | new webpack.optimize.CommonsChunkPlugin({ 256 | name: 'vendors', // 将公共模块提取,生成名为`vendors`的chunk 257 | chunks: ['index','list','about'], //提取哪些模块共有的部分 258 | minChunks: 3 // 提取至少3个模块共有的部分 259 | }), 260 | new ExtractTextPlugin('css/[name].css'), //单独使用link标签加载css并设置路径,相对于output配置中的publickPath 261 | 262 | //HtmlWebpackPlugin,模板生成相关的配置,每个对于一个页面的配置,有几个写几个 263 | new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML 264 | favicon: './src/img/favicon.ico', //favicon路径,通过webpack引入同时可以生成hash值 265 | filename: './view/index.html', //生成的html存放路径,相对于path 266 | template: './src/view/index.html', //html模板路径 267 | inject: 'body', //js插入的位置,true/'head'/'body'/false 268 | hash: true, //为静态资源生成hash值 269 | chunks: ['vendors', 'index'],//需要引入的chunk,不配置就会引入所有页面的资源 270 | minify: { //压缩HTML文件 271 | removeComments: true, //移除HTML中的注释 272 | collapseWhitespace: false //删除空白符与换行符 273 | } 274 | }), 275 | new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML 276 | favicon: './src/img/favicon.ico', //favicon路径,通过webpack引入同时可以生成hash值 277 | filename: './view/list.html', //生成的html存放路径,相对于path 278 | template: './src/view/list.html', //html模板路径 279 | inject: true, //js插入的位置,true/'head'/'body'/false 280 | hash: true, //为静态资源生成hash值 281 | chunks: ['vendors', 'list'],//需要引入的chunk,不配置就会引入所有页面的资源 282 | minify: { //压缩HTML文件 283 | removeComments: true, //移除HTML中的注释 284 | collapseWhitespace: false //删除空白符与换行符 285 | } 286 | }), 287 | new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML 288 | favicon: './src/img/favicon.ico', //favicon路径,通过webpack引入同时可以生成hash值 289 | filename: './view/about.html', //生成的html存放路径,相对于path 290 | template: './src/view/about.html', //html模板路径 291 | inject: true, //js插入的位置,true/'head'/'body'/false 292 | hash: true, //为静态资源生成hash值 293 | chunks: ['vendors', 'about'],//需要引入的chunk,不配置就会引入所有页面的资源 294 | minify: { //压缩HTML文件 295 | removeComments: true, //移除HTML中的注释 296 | collapseWhitespace: false //删除空白符与换行符 297 | } 298 | }), 299 | 300 | new webpack.HotModuleReplacementPlugin() //热加载 301 | ], 302 | //使用webpack-dev-server,提高开发效率 303 | devServer: { 304 | contentBase: './', 305 | host: 'localhost', 306 | port: 9090, //默认8080 307 | inline: true, //可以监控js变化 308 | hot: true, //热启动 309 | } 310 | }; 311 | ``` 312 | 好了,完成以上的这些配置之后,执行`webpack`打包命令完成项目打包。 313 | 314 | 此时,前往/dist/view目录下查看生成的list.html文件,如下: 315 | 316 | ```xml 317 | 318 | 319 | 320 | 321 | 列表页 322 | 323 | 324 | 325 |
    326 |
    327 | 328 |
    329 |
    330 | 331 | 332 | ``` 333 | 334 | 可以看到生成的文件除了保留原模板中的内容以外,还根据入口文件list.js的定义,自动添加需要引入CSS与JS文件,以及favicon,同时还添加了相应的hash值。 335 | 336 | 执行`webpack-dev-server`启动devServer,打开http://localhost:9090/dist/view/index.html就可以进行正常的页面预览了。说明我们的资源路径生成也是没有问题的。 337 | 338 | 好了,纯静态的webpack前端构建过程就是这样了。然而你可能还有疑问。 339 | 340 | - 假如你是个懒人,可能会觉得目前的配置不够智能,每增加一个页面,就得再手动添加入口文件及模板配置。 341 | - 假如你是个全栈工程师或者以nodejs做中间层的开发者,你的模板不是纯粹的html,但是又需要像html模板那样能自动根据需要添加css与js文件。 342 | 343 | 还等什么,快戳这里吧——[基于webpack的前端工程化开发之多页站点篇(二)](https://github.com/vhtml/webpack-MultiplePage) 344 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-front", 3 | "version": "1.0.0", 4 | "description": "pure front demo", 5 | "scripts": { 6 | "dev": "webpack-dev-server", 7 | "build": "webpack" 8 | }, 9 | "author": "vhtml", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "css-loader": "^0.23.1", 13 | "extract-text-webpack-plugin": "^1.0.1", 14 | "file-loader": "^0.8.5", 15 | "html-loader": "^0.4.3", 16 | "html-webpack-plugin": "^2.9.0", 17 | "jquery": "^1.12.0", 18 | "less": "^2.6.0", 19 | "less-loader": "^2.2.2", 20 | "style-loader": "^0.13.0", 21 | "url-loader": "^0.5.7", 22 | "webpack": "^1.12.13", 23 | "webpack-dev-server": "^1.14.1", 24 | "eslint": "^3.15.0", 25 | "eslint-config-standard": "^6.2.1", 26 | "eslint-loader": "^1.6.1", 27 | "eslint-plugin-html": "^2.0.0", 28 | "eslint-plugin-promise": "^3.4.1", 29 | "eslint-plugin-standard": "^2.0.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/css/common/global.css: -------------------------------------------------------------------------------- 1 | body{ 2 | font-family: "微软雅黑"; 3 | color:#333; 4 | } 5 | -------------------------------------------------------------------------------- /src/css/common/grid.css: -------------------------------------------------------------------------------- 1 | /*布局*/ 2 | .g-hd{ 3 | height: 50px; 4 | background-color: #333; 5 | } 6 | .g-bd{ 7 | padding: 20px; 8 | min-height: 800px; 9 | background: url(../../img/mask.png) repeat; 10 | } 11 | .g-ft{ 12 | height: 50px; 13 | background-color: #333; 14 | } 15 | -------------------------------------------------------------------------------- /src/css/lib/reset.css: -------------------------------------------------------------------------------- 1 | body,button,input,select,textarea{font:12px/1.414 Arial;color:#666;} 2 | body,h1,h2,h3,h4,h5,h6,dl,dt,dd,ul,ol,li,th,td,p,blockquote,pre,form,fieldset,legend,input,button,textarea,hr{margin:0; padding:0;} 3 | table{border-collapse:collapse;border-spacing:0;} 4 | li{list-style:none;} 5 | fieldset,img{border:0;} 6 | q:before,q:after{content:'';} 7 | input,textarea{outline-style:none;} 8 | input[type="text"],input[type="password"],textarea{outline-style:none;-webkit-appearance:none;} 9 | textarea{resize:none} 10 | address,caption,cite,code,dfn,em,i,th,var{font-style:normal;font-weight:normal;} 11 | legend{color:#000;} 12 | abbr,acronym {border:0;font-variant:normal;} 13 | a{text-decoration:none; color:#999;} 14 | a:hover{text-decoration:none;} 15 | 16 | .clearfix:after { 17 | clear: both; 18 | content: "."; 19 | display: block; 20 | height: 0; 21 | visibility: hidden; 22 | } 23 | -------------------------------------------------------------------------------- /src/css/page/about.less: -------------------------------------------------------------------------------- 1 | #about{ 2 | padding: 20px 0; 3 | color:blue; 4 | font-size: 20px; 5 | } -------------------------------------------------------------------------------- /src/css/page/index.less: -------------------------------------------------------------------------------- 1 | .text{ 2 | padding: 20px 0; 3 | font-size: 18px; 4 | color:#f63; 5 | } 6 | .btn{ 7 | width: 120px; 8 | height: 36px; 9 | line-height: 36px; 10 | background-color: #677D7C; 11 | color:#fff; 12 | text-align: center; 13 | border:none; 14 | box-shadow: 0 1px 3px #999; 15 | font-size: 16px; 16 | cursor: pointer; 17 | } 18 | .img{ 19 | margin-top: 20px; 20 | } 21 | -------------------------------------------------------------------------------- /src/css/page/list.less: -------------------------------------------------------------------------------- 1 | #list{ 2 | padding:20px 0; 3 | li{ 4 | line-height: 24px; 5 | color:red; 6 | border-bottom: 1px solid #ddd; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vhtml/webpack-MultiPage-static/b50b18095e31b9e62014fe85b5c1971c39576d95/src/img/4.png -------------------------------------------------------------------------------- /src/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vhtml/webpack-MultiPage-static/b50b18095e31b9e62014fe85b5c1971c39576d95/src/img/favicon.ico -------------------------------------------------------------------------------- /src/img/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vhtml/webpack-MultiPage-static/b50b18095e31b9e62014fe85b5c1971c39576d95/src/img/mask.png -------------------------------------------------------------------------------- /src/js/components/dialog/css/dialog.css: -------------------------------------------------------------------------------- 1 | .v-dialog{ 2 | position: fixed; 3 | display: none; 4 | left: 0;top:0;right:0;bottom:0; 5 | background-color: rgba(0,0,0,.5); 6 | } 7 | .v-dialog .close{ 8 | position: absolute; 9 | top:20px; 10 | right: 20px; 11 | width: 40px; 12 | height: 40px; 13 | border-radius: 50%; 14 | text-align: center; 15 | line-height: 40px; 16 | font-size: 40px; 17 | color:#666; 18 | background-color: rgba(255,255,255,.8); 19 | cursor: pointer; 20 | } 21 | .v-dialog .img{ 22 | position: absolute; 23 | margin:auto; 24 | top:0;right: 0;bottom:0;left: 0; 25 | max-width: 90%; 26 | max-height: 90%; 27 | } 28 | -------------------------------------------------------------------------------- /src/js/components/dialog/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vhtml/webpack-MultiPage-static/b50b18095e31b9e62014fe85b5c1971c39576d95/src/js/components/dialog/img/1.png -------------------------------------------------------------------------------- /src/js/components/dialog/index.js: -------------------------------------------------------------------------------- 1 | // 加载模块css 2 | require('./css/dialog.css') 3 | // 加载模板 4 | var html = require('./tmpl/dialog.html') 5 | 6 | /* eslint-disable no-undef */ 7 | module.exports = function () { 8 | var $dialog = $(html).clone() 9 | $dialog.find('.close').on('click', function () { 10 | $dialog.fadeOut(function () { 11 | $(this).remove() 12 | }) 13 | }) 14 | $('body').append($dialog) 15 | $dialog.fadeIn() 16 | } 17 | -------------------------------------------------------------------------------- /src/js/components/dialog/tmpl/dialog.html: -------------------------------------------------------------------------------- 1 |
    2 | × 3 | 4 |
    5 | -------------------------------------------------------------------------------- /src/js/page/about.js: -------------------------------------------------------------------------------- 1 | // 引入css 2 | require('../../css/lib/reset.css') 3 | require('../../css/common/global.css') 4 | require('../../css/common/grid.css') 5 | require('../../css/page/about.less') 6 | 7 | /* eslint-disable no-undef */ 8 | $('#about').html('这是一个关于webpack构建工程的栗子') 9 | -------------------------------------------------------------------------------- /src/js/page/index.js: -------------------------------------------------------------------------------- 1 | // 引入css 2 | require('../../css/lib/reset.css') 3 | require('../../css/common/global.css') 4 | require('../../css/common/grid.css') 5 | require('../../css/page/index.less') 6 | 7 | /* eslint-disable no-undef */ 8 | $('.g-bd').append('

    这是由js生成的一句话。

    ') 9 | 10 | // 增加事件 11 | $('.btn').click(function () { 12 | require.ensure(['../components/dialog/index.js'], function (require) { 13 | var Dialog = require('../components/dialog/index.js') 14 | new Dialog() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /src/js/page/list.js: -------------------------------------------------------------------------------- 1 | // 引入css 2 | require('../../css/lib/reset.css') 3 | require('../../css/common/global.css') 4 | require('../../css/common/grid.css') 5 | require('../../css/page/list.less') 6 | 7 | var html = '' 8 | for (var i = 0; i < 5; i++) { 9 | html += '
  • 列表' + (i + 1) + '
  • ' 10 | } 11 | /* eslint-disable no-undef */ 12 | $('#list').html(html) 13 | -------------------------------------------------------------------------------- /src/view/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 关于 6 | 7 | 8 | 9 |
    10 |
    11 |
    12 |
    13 |
    14 | 15 | -------------------------------------------------------------------------------- /src/view/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 首页 6 | 7 | 10 | 11 | 12 |
    13 |
    14 | 15 |

    16 | 17 |

    18 |
    19 |
    20 | 23 | 24 | -------------------------------------------------------------------------------- /src/view/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 列表页 6 | 7 | 8 | 9 |
    10 |
    11 | 12 |
    13 |
    14 | 15 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | /* 4 | extract-text-webpack-plugin插件, 5 | 有了它就可以将你的样式提取到单独的css文件里, 6 | 妈妈再也不用担心样式会被打包到js文件里了。 7 | */ 8 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 9 | /* 10 | html-webpack-plugin插件,重中之重,webpack中生成HTML的插件, 11 | 具体可以去这里查看https://www.npmjs.com/package/html-webpack-plugin 12 | */ 13 | var HtmlWebpackPlugin = require('html-webpack-plugin') 14 | 15 | module.exports = { 16 | // 配置入口文件,有几个写几个 17 | entry: { 18 | index: './src/js/page/index.js', 19 | list: './src/js/page/list.js', 20 | about: './src/js/page/about.js' 21 | }, 22 | output: { 23 | path: path.join(__dirname, 'dist'), // 输出目录的配置,模板、样式、脚本、图片等资源的路径配置都相对于它 24 | publicPath: '/', // 模板、样式、脚本、图片等资源对应的server上的路径 25 | filename: 'js/[name].js', // 每个页面对应的主js的生成配置 26 | chunkFilename: 'js/[id].chunk.js' // chunk生成的配置 27 | }, 28 | module: { 29 | // 加载器,关于各个加载器的参数配置,可自行搜索之。 30 | loaders: [ 31 | { 32 | test: /\.css$/, 33 | // 配置css的抽取器、加载器。'-loader'可以省去 34 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader') 35 | }, { 36 | test: /\.less$/, 37 | // 配置less的抽取器、加载器。中间!有必要解释一下, 38 | // 根据从右到左的顺序依次调用less、css加载器,前一个的输出是后一个的输入 39 | // 你也可以开发自己的loader哟。有关loader的写法可自行谷歌之。 40 | loader: ExtractTextPlugin.extract('css!less') 41 | }, { 42 | // html模板加载器,可以处理引用的静态资源,默认配置参数attrs=img:src,处理图片的src引用的资源 43 | // 比如你配置,attrs=img:src img:data-src就可以一并处理data-src引用的资源了,就像下面这样 44 | test: /\.html$/, 45 | loader: 'html?attrs=img:src img:data-src' 46 | }, { 47 | // 文件加载器,处理文件静态资源 48 | test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, 49 | loader: 'file-loader?name=./fonts/[name].[ext]' 50 | }, { 51 | // 图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求 52 | // 如下配置,将小于8192byte的图片转成base64码 53 | test: /\.(png|jpg|gif)$/, 54 | loader: 'url-loader?limit=8192&name=./img/[hash].[ext]' 55 | } 56 | ] 57 | }, 58 | plugins: [ 59 | new webpack.ProvidePlugin({ // 加载jq 60 | $: 'jquery' 61 | }), 62 | new webpack.optimize.CommonsChunkPlugin({ 63 | name: 'vendors', // 将公共模块提取,生成名为`vendors`的chunk 64 | chunks: ['index', 'list', 'about'], // 提取哪些模块共有的部分 65 | minChunks: 3 // 提取至少3个模块共有的部分 66 | }), 67 | new ExtractTextPlugin('css/[name].css'), // 单独使用link标签加载css并设置路径,相对于output配置中的publickPath 68 | 69 | // HtmlWebpackPlugin,模板生成相关的配置,每个对于一个页面的配置,有几个写几个 70 | new HtmlWebpackPlugin({ // 根据模板插入css/js等生成最终HTML 71 | favicon: './src/img/favicon.ico', // favicon路径,通过webpack引入同时可以生成hash值 72 | filename: './index.html', // 生成的html存放路径,相对于path 73 | template: './src/view/index.html', // html模板路径 74 | inject: 'body', // js插入的位置,true/'head'/'body'/false 75 | hash: true, // 为静态资源生成hash值 76 | chunks: ['vendors', 'index'], // 需要引入的chunk,不配置就会引入所有页面的资源 77 | minify: { // 压缩HTML文件 78 | removeComments: true, // 移除HTML中的注释 79 | collapseWhitespace: false // 删除空白符与换行符 80 | } 81 | }), 82 | new HtmlWebpackPlugin({ // 根据模板插入css/js等生成最终HTML 83 | favicon: './src/img/favicon.ico', // favicon路径,通过webpack引入同时可以生成hash值 84 | filename: './list.html', // 生成的html存放路径,相对于path 85 | template: './src/view/list.html', // html模板路径 86 | inject: true, // js插入的位置,true/'head'/'body'/false 87 | hash: true, // 为静态资源生成hash值 88 | chunks: ['vendors', 'list'], // 需要引入的chunk,不配置就会引入所有页面的资源 89 | minify: { // 压缩HTML文件 90 | removeComments: true, // 移除HTML中的注释 91 | collapseWhitespace: false // 删除空白符与换行符 92 | } 93 | }), 94 | new HtmlWebpackPlugin({ // 根据模板插入css/js等生成最终HTML 95 | favicon: './src/img/favicon.ico', // favicon路径,通过webpack引入同时可以生成hash值 96 | filename: './about.html', // 生成的html存放路径,相对于path 97 | template: './src/view/about.html', // html模板路径 98 | inject: true, // js插入的位置,true/'head'/'body'/false 99 | hash: true, // 为静态资源生成hash值 100 | chunks: ['vendors', 'about'], // 需要引入的chunk,不配置就会引入所有页面的资源 101 | minify: { // 压缩HTML文件 102 | removeComments: true, // 移除HTML中的注释 103 | collapseWhitespace: false // 删除空白符与换行符 104 | } 105 | }), 106 | 107 | new webpack.HotModuleReplacementPlugin() // 热加载 108 | ], 109 | // 使用webpack-dev-server,提高开发效率 110 | devServer: { 111 | contentBase: './', 112 | host: 'localhost', 113 | port: 9090, 114 | inline: true, 115 | hot: true 116 | } 117 | } 118 | --------------------------------------------------------------------------------