项目构建流程及webpack使用

项目结构与Git远程仓库的建立

如果你是从头开始一个新项目的话

  1. 在Github建立远程仓库
  2. 在本地新建项目的结构
  3. git初始化
git init
  1. 与远程库建立关联
//在Github上添加了你的主机公钥
git remote add origin ssh address
  1. 配置.gitignore
.DS_Store
/node_modules/
/dist
  1. 推送到远程
git add .
git commit -m "something"
git push -u origin master
  1. 当然,我们应该是在分支中完成项目的
git checkout -b dev

项目脚手架搭建

  1. npm 初始化
npm init
  1. webpack
npm install webpack -g    
npm install webpack@1.15.0 --save-dev    //为了兼容IE8,在项目安装
  1. webpack.config.js

当然,你不可能做一个项目采用命令行的方式打包吧

entry js的入口文件
externals 外部依赖的声明
output 目标文件
resolve 配置别名
module 各种文件,各种loader
plugins 插件

对脚本处理的一些问题

  • js用什么loader加载?
    由于考虑到IE8上的兼容性问题,因此不是用babel的loader加载方式,而使用webpack自带的js加载方式
  • 官方文档上的例子entry只有一个js,我们有多个怎么办?
var config = {
    entry: {
        'index':['./src/page/index/index.js'],
        'login':['./src/page/login/index.js']
    },
    output: {
        path: './dist',
        filename: '[name].js'    //需要注意的是多个入口文件如果不采用这种方式,入口文件会被依次覆盖
    }
};

module.exports = config
  • output里要分文件夹存放目标文件,怎么设置?
var config = {
    entry: {
        'index':['./src/page/index/index.js'],
        'login':['./src/page/login/index.js']
    },
    output: {
        path: './dist',
        filename: '/js/[name].js'    //filename是支持路径的,我们可以在这里去指定路径
    }
};

module.exports = config
  • jquery引入方法
    其实有两种方法,其中一种是通过require的方式引入
'use strict';
var $ = require('jquery');
console.log('hello index');

$('body').html('HELLO INDEX');

但是这种方法不好的地方在于我每个文件几乎我都需要引入jquery,这就很麻烦了,麻烦的事我们都不喜欢做..

<script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>

恩,这样就解决了,哦注意一点是jquery2.0以后就和IE8说再见了,所以要用1.××的
但是,我们想用模块化的方式引入jquery呢?

//index.js
'use strict';
console.log('hello index');

var $$ = require('jquery');    //没有在npm安装jquery

$$('body').html('index hello ~~~~~~');
var config = {
    entry: {
        'index':['./src/page/index/index.js'],
        'login':['./src/page/login/index.js']
    },
    output: {
        path: './dist',
        filename: '/js/[name].js'
    },
    externals:{
        'jquery':'window.jQuery'      //引入外部的变量或模块加载进来
    }
};

module.exports = config
  • 我想提取出公共模块,怎么处理?
    CommonsChunkPlugin
    恩,这个细讲讲
    首先如果你每个文件都引入同一个模块的话,那么它应该就是一个通用组件了
var webpack = require('webpack');
var config = {
    entry: {
        'index':['./src/page/index/index.js'],
        'login':['./src/page/login/index.js']
    },
    output: {
        path: './dist',
        filename: '/js/[name].js'
    },
    externals:{
        'jquery':'window.jQuery'
    },
    plugins:[
        new webpack.optimize.CommonsChunkPlugin({     //介个就拷贝吧,谁记介个
            name:'commons',     //存的文件名,commons是默认的
            filename:'js/base.js'   //最后输出的文件名,filename都是基于output的path
    //index和login都引入了相同的模块,因此,它会将这个通用的模块引入进base.js中
        })
    ]
};

module.exports = config

但是我每个文件都引入相同模块我还要写一句require(),我不想写...

var webpack = require('webpack');
var config = {
    entry: {
        'common':['./src/page/common/index.js'],
        'index':['./src/page/index/index.js'],
        'login':['./src/page/login/index.js']
    },
    output: {
        path: './dist',
        filename: '/js/[name].js'
    },
    externals:{
        'jquery':'window.jQuery'
    },
    plugins:[
        new webpack.optimize.CommonsChunkPlugin({     
            name:'common',     //这个common和entry的common对应,否则common会生成common.js而不是base.js
            filename:'js/base.js'   
        })
    ]
};

module.exports = config

对样式处理的一些问题

  • 样式使用怎样的CSS loader?
    **css-loader style-loader **

安装css-loader style-loader

npm install css-loader style-loader --save-dev

js引入css文件

//index.js
'use strict';
console.log('hello index');
require('./index.css');
require('../module.js');
//webpack.config.js
var webpack = require('webpack');
var config = {
    entry: {
        'common':['./src/page/common/index.js'],
        'index':['./src/page/index/index.js'],
        'login':['./src/page/login/index.js']
    },
    output: {
        path: './dist',
        filename: '/js/[name].js'
    },
    externals:{
        'jquery':'window.jQuery'
    },
    module:{
      loaders:[
          {test:/\.css$/,loader:"style-loader!css-loader"}   
          //从右往左,先执行css-loader再执行style-loader
      ]
    },
    plugins:[
        new webpack.optimize.CommonsChunkPlugin({
            name:'common',     base.js
            filename:'js/base.js'
        })
    ]
};

module.exports = config
  • webpack打包的CSS怎么独立成单独的文件?
    extract-text-webpack-plugin
npm install extract-text-webpack-plugin --save-dev

如果报错选择较低版本

npm install extract-text-webpack-plugin@1.0.1 --save-dev
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');     //1.引入
var config = {
    entry: {
        'common':['./src/page/common/index.js'],
        'index':['./src/page/index/index.js'],
        'login':['./src/page/login/index.js']
    },
    output: {
        path: './dist',
        filename: '/js/[name].js'
    },
    externals:{
        'jquery':'window.jQuery'
    },
    module:{
      loaders:[
          {test:/\.css$/,loader:ExtractTextPlugin.extract("style-loader","css-loader")}     //2.做一次转化
      ]
    },
    plugins:[
        new webpack.optimize.CommonsChunkPlugin({
            name:'common',    
            filename:'js/base.js'
        }),
        new ExtractTextPlugin("css/[name].css")     //3.添加dist路径
    ]
};

module.exports = config

对html模板处理的问题

html-webpack-plugin

我们为什么要进行html模板处理呢?如果现在我们上线了,后来再改,你的一些引入的文件是要加版本号的,但是有几十个页面,每个页面都要加版本号,那不得急死...而且html文件是在src目录下,并不在dist目录下,我们打包后,src是不管的.因此,我们要对我们的html进行一些配置

插件链接: https://webpack.js.org/plugins/html-webpack-plugin/

参数:

  • title: title值用于生成的HTML文档。

  • filename: 将生成的HTML写入到该文件中。默认写入到index.html中。你也可以在这儿指定子目录 (eg: assets/admin.html)。

  • template: Webpack require path 到 template中。 详情查阅 docs

  • inject:true | 'head' | 'body' | false添加所有的静态资源(assets)到模板文件或templateContent 。当传入truebody时,所有javascript资源将被放置到body 元素的底部。 当传入head时, 所有的脚本将被放置到head元素中。

  • favicon: 添加指定的favicon path到输出的html文件。

  • minify:{...} | false传入一个html-minifier 对象选项来压缩输出的html文件。

  • hash:true | false如果值为true,就添加一个唯一的webpack compilation hash给所有已included的 scripts 和 CSS 文件。这对缓存清除(cache busting)十分有用。

  • cache:true | false如果为true (默认),只要文件被更改了就emit(发表)文件。

  • showErrors:true | false如果为true (默认),详细的错误信息将被写入到HTML页面。

  • chunks:允许你只添加某些chunks (e.g. only the unit-test chunk)

  • chunksSortMode: 在chunks被include到html文件中以前,允许你控制chunks 应当如何被排序。允许的值:'none' | 'auto' | 'dependency' | {function}默认值:'auto'

  • excludeChunks: 允许你跳过某些chunks (e.g. don't add the unit-test chunk)

  • xhtml:true | false如果为true, 将 link 标签渲染为自闭合标签, XHTML compliant。 默认是 false。

参数参考自: 前端xiyoki链接://www.greatytc.com/p/2c849a445a91

流程

npm install html-webpack-plugin --save-dev
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var htmlWebpackPlugin = require('html-webpack-plugin');     //1.引入

//获取html-webpack-plugin获取参数的方法
var getHtmlConfig = function(name){
    return {
        template:'./src/view/' + name +'.html',
        filename:'view/' + name + '.html',
        inject:true,
        hash:true,
        chunks:['common',name]
    }
}

var config = {
    entry: {
        'common':['./src/page/common/index.js'],
        'index':['./src/page/index/index.js'],
        'login':['./src/page/login/index.js']
    },
    output: {
        path: './dist',
        filename: 'js/[name].js'
    },
    externals:{
        'jquery':'window.jQuery'
    },
    module:{
      loaders:[
          {test:/\.css$/,loader:ExtractTextPlugin.extract("style-loader","css-loader")}
      ]
    },
    plugins:[
        //独立通用模块js/base.js
        new webpack.optimize.CommonsChunkPlugin({
            name:'common',
            filename:'js/base.js'
        }),
        //把css单独打包到文件里
        new ExtractTextPlugin("css/[name].css"),
        //html模板的处理
        new htmlWebpackPlugin(getHtmlConfig('index')),
        new htmlWebpackPlugin(getHtmlConfig('login'))
    ]
};

module.exports = config

ok,我们的自动打包html模板就大功告成了.但是我们每次打包的时候都需要有个初始的html文件

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
</body>
</html>

我们需要每个文件都加上那么一句jquery的引用好麻烦啊
由于我们后面需要这个html-loader作为中介

npm install html-loader --save-dev

嗯,我们把head抽离出来

//html-head.html
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
//index.html
<!doctype html>
<html lang="en">
<%= require('html-loader!./layout/html-head.html') %>
<body>

<script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
</body>
</html>

对图片处理的问题

npm install url-loader --save-dev

此种情况会将你的图片转为base64格式存在css文件中

...
module:{
  loaders:[
      {test:/\.css$/,loader:ExtractTextPlugin.extract("style-loader","css-loader")},
      {test:/\.(gif|png|jpg)\??.*$/,loader:'url-loader'},
  ]
},
...

当然好处是你减少请求了,但是大的文件我们还是应该放一个地方从css文件中拿出来

npm install file-loader --save-dev
module:{
      loaders:[
          {test:/\.css$/,loader:ExtractTextPlugin.extract("style-loader","css-loader")},
          {test:/\.(gif|png|jpg|jpeg)\??.*$/,loader:'file-loader?limit=1000&name=resource/[name].[ext]'}
      ]
    },

这一块是有疑问的- -...等我解决了会更新,url-loader添加参数报错

对icon-font处理的问题

module:{
  loaders:[
      {test:/\.css$/,loader:ExtractTextPlugin.extract("style-loader","css-loader")},
      {test:/\.(gif|png|jpg|woff|svg|eot|ttf)\??.*$/,loader:'file-loader?limit=1000&name=resource/[name].[ext]'}
      //只需要在这里加入扩展名
  ]
},

webpack-dev-server

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

webpack版本问题因此我们选择低版本了

npm install webpack-dev-server@1.16.5  --save-dev 

为了能够使用命令要在全局安装webpack-dev-server

npm install webpack-dev-server  -g

执行webpack-dev-server,发现我们使用的是它的iframe方式,这种方式不利于我们做调试,因此我们采取另外一种方式
首先,我们要将webpack-dev-server的代理放置在页面上,而common这个公共模块是所有页面都有的,因此:

//webpack.config.js
...
entry: {
    'common':['./src/page/common/index.js','webpack-dev-server/client?http://localhost:8088/'],    //设置代理
    'index':['./src/page/index/index.js'],
    'login':['./src/page/login/index.js']
},
...

执行命令:

webpack-dev-server --inline --port 8088

但是由于webpack-dev-server的路径是'/',我们的路径是'../',因此我们要指定一下页面访问的路径

//webapck.config.js
...
output: {
    path: './dist',
    publicPath:'/dist',      //页面的访问路径
    filename: '/js/[name].js'
},  
...

但是我们webpack-dev-server的这个模块不是我们线上的时候需要的,因此进行如下配置

//webapck.config.js
...
//环境变量配置    dev  /  online
var WEBPACK_ENV  =  process.env.WEBPACK_ENV  ||  'dev'
console.log(WEBPACK_ENV)

//做判断
if(WEBPACK_ENV === 'dev'){
    config.entry.common.push('webpack-dev-server/client?http://localhost:8088/')
}
entry: {
    'common':['./src/page/common/index.js'],
    'index':['./src/page/index/index.js'],
    'login':['./src/page/login/index.js']
},
...

最后别忘了删除common中的webpack-dev-server配置
此时,执行命令

WEBPACK_ENV=dev  webpack-dev-server --inline --port 8088

OK,我们的webpack-dev-server基本上都配置好了,下面我们来优化一下我们的npm命令

//package.json
...
"scripts": {
    "dev" : "WEBPACK_ENV=dev  webpack-dev-server --inline --port 8088",
    "dev_win" : "set WEBPACK_ENV=dev && webpack-dev-server --inline --port 8088",
    "dist": "WEBPACK_ENV=online  webpack -p",
    "dist_win": "set WEBPACK_ENV=online && webpack -p"
},
...

执行:

npm run dev
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355