直接上步骤

一、创建项目

1. 使用VSCode建立项目目录结构如下:

文档结构

wabg
├── http
│   ├── app.js
│   ├── controllers
│   │   └── index.js
│   ├── directives
│   │   └── index.js
│   ├── services
│   │   └── index.js
│   ├── templates
│   │   └── index.tmpl.html
│   └── views
│       └── index.js
├── package.json
└── webpack.config.js

二、配置webpack和angularjs

1. 安装webpack和angularjs所需的依赖项

npm install webpack webpack-dev-server angular angular-ui-router jquery html-webpack-plugin ngtemplate-loader html-loader --save-dev

2. 创建一个简单的页面,通过这个非常简单的页面,验证webpack和angular各要素是否能够正常使用,该页面要素包括:

红色部分是点击“getAuthor”按钮后由AngularJS的Controller赋值而出现的;

蓝色部分是通过一个directive渲染的

绿色部分是通过jQuery动态添加的

文档结构如下:

wabg
├── dist
│   ├── index.html
│   └── js
│       ├── angular.bundle.js
│       ├── angular.bundle.js.map
│       ├── app.bundle.js
│       ├── app.bundle.js.map
│       ├── vendor.bundle.js
│       └── vendor.bundle.js.map
├── http
│   ├── app.js
│   ├── controllers
│   │   ├── home
│   │   │   └── home.controller.js
│   │   └── index.js
│   ├── directives
│   │   ├── demo
│   │   │   └── demo.directive.js
│   │   └── index.js
│   ├── services
│   │   └── index.js
│   ├── templates
│   │   └── index.tmpl.html
│   └── views
│       ├── demo
│       │   └── demo.view.html
│       └── index.js
├── package.json
└── webpack.config.js

下面为本页面用到的所有代码

2.  /webpack.config.js  文件

'use strict';
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    devtool: 'evel-source-map',
    context: path.resolve(__dirname + '/http'),
    entry: {
        app: './app.js',
        vendor: ['jquery'],
        angular: ['angular', 'angular-ui-router']
    },
    output: {
        path: path.resolve(__dirname + '/dist'),
        filename: 'js/[name].bundle.js',
        publicPath: '',
    },
    devServer: {
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [
            {
                test: /\.view.html$/,
                use: [
                    {
                        loader: 'ngtemplate-loader'
                    },
                    {
                        loader: 'html-loader'
                    }
                ],
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: __dirname + '/http/templates/index.tmpl.html',
            chunksSortMode: function (chunk1, chunk2) {
                var order = ['angular', 'vendor', 'app'];
                var order1 = order.indexOf(chunk1.names[0]);
                var order2 = order.indexOf(chunk2.names[0]);
                return order1 - order2;
            }
        }),
        new webpack.optimize.CommonsChunkPlugin({
            names: ['vendor', 'angular'],
            filename: 'js/[name].bundle.js'
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery'
        })
    ]
};
View Code

3.  /http/app.js 文件

'use strict';
var angular = require('angular');
var uirouter = require('angular-ui-router');

var services = require('./services');
var views = require('./views');
var directives = require('./directives');
var controllers = require('./controllers');

angular.module('wabgApp', [uirouter.default, services.default, views.default, directives.default, controllers.default]);
View Code

4.  /http/services/index.js 文件

'use strict';
var angular = require('angular');

var servicesModule = angular.module('wabgApp.services', []);

exports = module.exports = {
    default: servicesModule.name
};
View Code

5.  /http/controllers/index.js 文件

'use strict';
var angular = require('angular');

var homeController = require('./home/home.controller');

var controllersModule = angular.module('wabgApp.controllers', [])
    .controller(homeController.name, ['$scope', homeController]);

exports = module.exports = {
    default: controllersModule.name,
    homeController: homeController.name
};
View Code

6.  /http/controllers/home/home.controller.js  文件

'use strict';

function homeController($scope) {
    $scope.name = 'think8848';
    $scope.getAuthor = function (name) {
        $scope.author = name;
    };
}

exports = module.exports = homeController;
View Code

7.  /http/directives/index.js 文件

'use strict';
var angular = require('angular');

var demoDirective = require('./demo/demo.directive');

var directivesModule = angular.module('wabgApp.directives', [])
    .directive(demoDirective.name, ['views', demoDirective]);

exports = module.exports = {
    default: directivesModule.name,
    demoDirective: demoDirective.name
};
View Code

8.  /http/directives/demo/demo.directive.js 文件

'use strict';

function demoDirective(views) {
    return {
        restrict: 'E',
        templateUrl: views.demo,
        link: function (scope, elem) {
            $(elem).after('<div style="color: green">The content generated by jQuery</div>');
        }
    };
}

exports = module.exports = demoDirective;
View Code

9.  /http/views/index.js 文件

'use strict';
var angular = require('angular');

function views() {
    return {
        demo: require('./demo/demo.view.html')
    };
}

exports = module.exports = views();

var viewsModule = angular.module('wabgApp.views', [])
    .constant(views.name, exports);

exports.default = viewsModule.name;
View Code

10.  /http/views/demo/demo.view.html 文件

<div style="color:blue">This is a demo directive.</div>
<br/>
View Code

11.  /http/templates/index.tmpl.html 文件

<!DOCTYPE html>
<html ng-app="wabgApp">

<head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
    <style>
        .ng-cloak {
            display: none;
        }
    </style>
</head>

<body>
    <div id="root" ng-controller="homeController">
        The Author is:
        <lable ng-ng-cloak class="ng-cloak" style="color:red">{{author}}</lable><br/>
        <input type="button" ng-click="getAuthor(name)" value="getAuthor" />
        <br/>
        <br/>
        <demo-directive></demo-directive>
    </div>
</body>

</html>
View Code

12. 修改 package.json 文件中的 scripts 节点如下:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack",
    "server": "webpack-dev-server --open"
  },

13. 运行 npm run server 命令

运行界面效果 

 

 三、加入Bootstrap 4.0支持

1. 当前Bootstrap的最新版本是v4.0 Beta,在使用webpack时有两点需要注意:一是默认的样式文件为 scss 样式;二是当前v4.0 Beta版中默认不提供图标了。首先依然是安装依赖项

npm install bootstrap@4.0.0-beta  expose-loader style-loader css-loader postcss-loader precss autoprefixer sass-loader url-loader file-loader popper.js exports-loader node-sass --save-dev

2. 为Bootstrap加入图标支持,图标使用FontAwesome(官网)

2.1 先下载Bootstrap 4.0.0 beta版(本人虽不是前端,但是对前端框架和库的版本也无力吐槽了)的源代码,友情提示:经测试 npm 上下载的发布包是无法顺利集成图标的

git clone https://github.com/twbs/bootstrap.git

2.2 下载FontAwesome字体包(本文下载到的版本是v4.7.0)

2.3 将下载好的FontAwesome解压后,相关的子目录放到指定位置

 font-awesome 和 scss 放到 bootstrap 源代码根目录下, fonts 放到 bootstrap 源代码的 dist 目录下

2.4 使用VSCode打开 bootstrap 源代码根目录,修改 /scss/bootstrap.scss  文件,在最下面添加两行代码,注意:一定要在文件最后保留一行空行

$fa-font-path: "../fonts";
@import "../font-awesome/scss/font-awesome.scss";

 

2.5 使用 npm install 下载依赖项,然后再使用 npm run dist 命令发布

在发布的过程中,跳出来很多绿的,蓝的说明没问题,过会儿就好了

2.6 使用源代码包中的内容替换 wabg 项目中 node_modules/bootstrap 中的相应文件夹

 2.7 编辑 /wabg/node_modules/bootstrap/scss/bootstrap.scss  文件,将之前代码上级目录的 ../ 替换为 ~bootstrap/ ,在 fonts 目录前面加上 dist 目录

 至此,Bootstrap的准备工作完成,下面开始添加演示代码,项目文档结构如下:

wabg
├── dist
│   ├── index.html
│   └── js
│       ├── angular.bundle.js
│       ├── angular.bundle.js.map
│       ├── app.bundle.js
│       ├── app.bundle.js.map
│       ├── vendor.bundle.js
│       └── vendor.bundle.js.map
├── http
│   ├── app.js
│   ├── controllers
│   │   ├── home
│   │   │   └── home.controller.js
│   │   └── index.js
│   ├── directives
│   │   ├── demo
│   │   │   └── demo.directive.js
│   │   ├── index.js
│   │   └── menu
│   │       └── menu.directive.js
│   ├── scss
│   │   └── index.scss
│   ├── services
│   │   └── index.js
│   ├── templates
│   │   └── index.tmpl.html
│   └── views
│       ├── demo
│       │   └── demo.view.html
│       ├── index.js
│       └── menu
│           └── menu.view.html
├── package.json
└── webpack.config.js

3. 编辑 webpack.config.js 文件

'use strict';
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    devtool: 'evel-source-map',
    context: path.resolve(__dirname + '/http'),
    entry: {
        app: './app.js',
        vendor: ['jquery', 'popper.js', 'bootstrap', 'bootstrap/js/dist/util.js', 'bootstrap/js/dist/dropdown.js'],
        angular: ['angular', 'angular-ui-router']
    },
    output: {
        path: path.resolve(__dirname + '/dist'),
        filename: 'js/[name].bundle.js',
        publicPath: '',
    },
    devServer: {
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [
            {
                test: /\.view.html$/,
                use: [
                    {
                        loader: 'ngtemplate-loader'
                    },
                    {
                        loader: 'html-loader'
                    }
                ],
            },
            {
                test: /\.css$/,
                use: [{
                    loader: 'style-loader'
                }, {
                    loader: 'css-loader'
                }]
            },
            {
                test: /\.(scss)$/,
                use: [{
                    loader: 'style-loader',
                }, {
                    loader: 'css-loader',
                }, {
                    loader: 'postcss-loader',
                    options: {
                        plugins: function () {
                            return [
                                require('precss'),
                                require('autoprefixer')
                            ];
                        }
                    }
                }, {
                    loader: 'sass-loader'
                }]
            },
            {
                test: /\.(jpg|png|gif)(\?.*$|$)/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 10000,
                            name: './images/[name].[ext]'
                        }
                    }
                ]
            },
            {
                test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        name: './fonts/[name].[ext]'
                    }
                }]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: __dirname + '/http/templates/index.tmpl.html',
            chunksSortMode: function (chunk1, chunk2) {
                var order = ['angular', 'vendor', 'app'];
                var order1 = order.indexOf(chunk1.names[0]);
                var order2 = order.indexOf(chunk2.names[0]);
                return order1 - order2;
            }
        }),
        new webpack.optimize.CommonsChunkPlugin({
            names: ['vendor', 'angular'],
            filename: 'js/[name].bundle.js'
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            Popper: ['popper.js', 'default'],
            Util: 'exports-loader?Util!bootstrap/js/dist/util',
            Dropdown: 'exports-loader?Dropdown!bootstrap/js/dist/dropdown'
        })
    ]
};
View Code

4. 修改 /http/app.js 文件

'use strict';
var angular = require('angular');
var uirouter = require('angular-ui-router');

var scss = require('./scss/index.scss');

var services = require('./services');
var directives = require('./directives');
var controllers = require('./controllers');
var views = require('./views');

angular.module('wabgApp', [uirouter.default, services.default, views.default, directives.default, controllers.default]);
View Code

5. 编辑 /http/directives/index.js 文件

'use strict';
var angular = require('angular');

var demoDirective = require('./demo/demo.directive');
var menuDirective = require('./menu/menu.directive');

var directivesModule = angular.module('wabgApp.directives', [])
    .directive(demoDirective.name, ['views', demoDirective])
    .directive(menuDirective.name, ['views', menuDirective]);

exports = module.exports = {
    default: directivesModule.name,
    demoDirective: demoDirective.name,
    menuDirective: menuDirective
};
View Code

6. 创建 /http/directives/menu/menu.directive.js 文件

'use strict';

function menuDirective(views) {
    return {
        restrict: 'E',
        templateUrl: views.menu
    };
}

exports = module.exports = menuDirective;
View Code

7. 编辑 /http/views/index.js  文件

'use strict';
var angular = require('angular');

function views() {
    return {
        demo: require('./demo/demo.view.html'),
        menu: require('./menu/menu.view.html')
    };
}

exports = module.exports = views();

var viewsModule = angular.module('wabgApp.views', [])
    .constant(views.name, exports);

exports.default = viewsModule.name;
View Code

8. 创建 /http/views/menu/menu.view.html 文件

<nav class="navbar navbar-light bg-light">
  <a class="navbar-brand" href="#">
      <span  width="30" height="30" class="d-inline-block align-top fa fa-camera-retro fa-5x" />
      Bootstrap
    </a>
</nav>
View Code

9. 修改 /http/templates/index.tmpl.html 文件

<!DOCTYPE html>
<html ng-app="wabgApp">

<head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
    <style>
        .ng-cloak {
            display: none;
        }
    </style>
</head>

<body>
    <div id="root" ng-controller="homeController">
        <menu-directive></menu-directive>
        The Author is:
        <lable ng-ng-cloak class="ng-cloak" style="color:red">{{author}}</lable><br/>
        <input type="button" ng-click="getAuthor(name)" value="getAuthor" />
        <br/>
        <br/>
        <demo-directive></demo-directive>
    </div>
</body>

</html>
View Code

10 创建 /http/scss/index.scss 文件

@import "~bootstrap/scss/bootstrap";
View Code

11. 运行  npm run server 就能看到效果了

 

 四、加入Mapbox-gl支持

1. 安装依赖项

npm install mapbox-gl angular-mapboxgl-directive --save-dev

 2. 下面演示的是AngularJS中使用MapBox-gl-js,为了显示效果,加入了一个很简单的About页面,用于演示地图和普通VIew的切换。如下图所示:

项目目录结构如下

wabg
├── dist
│   ├── fonts
│   │   ├── fontawesome-webfont.eot
│   │   ├── fontawesome-webfont.svg
│   │   ├── fontawesome-webfont.ttf
│   │   ├── fontawesome-webfont.woff
│   │   └── fontawesome-webfont.woff2
│   ├── index.html
│   └── js
│       ├── angular.bundle.js
│       ├── angular.bundle.js.map
│       ├── app.bundle.js
│       ├── app.bundle.js.map
│       ├── vendor.bundle.js
│       └── vendor.bundle.js.map
├── http
│   ├── app.js
│   ├── controllers
│   │   ├── about
│   │   │   └── about.controller.js
│   │   ├── home
│   │   │   └── home.controller.js
│   │   ├── index.js
│   │   └── map
│   │       └── map.controller.js
│   ├── css
│   │   └── index.css
│   ├── directives
│   │   ├── demo
│   │   │   └── demo.directive.js
│   │   ├── index.js
│   │   └── menu
│   │       └── menu.directive.js
│   ├── scss
│   │   └── index.scss
│   ├── services
│   │   ├── index.js
│   │   └── map-styles
│   │       └── default-style.js
│   ├── templates
│   │   └── index.tmpl.html
│   └── views
│       ├── about
│       │   └── about.view.html
│       ├── demo
│       │   └── demo.view.html
│       ├── index.js
│       ├── map
│       │   └── map.view.html
│       └── menu
│           └── menu.view.html
├── package.json
└── webpack.config.js

3. 修改 webpack.config.js 文件

'use strict';
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    devtool: 'evel-source-map',
    context: path.resolve(__dirname + '/http'),
    entry: {
        app: './app.js',
        vendor: ['jquery', 'popper.js', 'bootstrap', 'bootstrap/js/dist/util.js', 'bootstrap/js/dist/dropdown.js', 'mapbox-gl', 'angular-mapboxgl-directive'],
        angular: ['angular', 'angular-ui-router']
    },
    output: {
        path: path.resolve(__dirname + '/dist'),
        filename: 'js/[name].bundle.js',
        publicPath: '',
    },
    devServer: {
        historyApiFallback: true,
        inline: true
    },
    module: {
        rules: [
            {
                test: /\.view.html$/,
                use: [
                    {
                        loader: 'ngtemplate-loader'
                    },
                    {
                        loader: 'html-loader'
                    }
                ],
            },
            {
                test: /\.css$/,
                use: [{
                    loader: 'style-loader'
                }, {
                    loader: 'css-loader'
                }]
            },
            {
                test: /\.(scss)$/,
                use: [{
                    loader: 'style-loader',
                }, {
                    loader: 'css-loader',
                }, {
                    loader: 'postcss-loader',
                    options: {
                        plugins: function () {
                            return [
                                require('precss'),
                                require('autoprefixer')
                            ];
                        }
                    }
                }, {
                    loader: 'sass-loader'
                }]
            },
            {
                test: /\.(jpg|png|gif)(\?.*$|$)/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 10000,
                            name: './images/[name].[ext]'
                        }
                    }
                ]
            },
            {
                test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        name: './fonts/[name].[ext]'
                    }
                }]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: __dirname + '/http/templates/index.tmpl.html',
            chunksSortMode: function (chunk1, chunk2) {
                var order = ['angular', 'vendor', 'app'];
                var order1 = order.indexOf(chunk1.names[0]);
                var order2 = order.indexOf(chunk2.names[0]);
                return order1 - order2;
            }
        }),
        new webpack.optimize.CommonsChunkPlugin({
            names: ['vendor', 'angular'],
            filename: 'js/[name].bundle.js'
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            Popper: ['popper.js', 'default'],
            Util: 'exports-loader?Util!bootstrap/js/dist/util',
            Dropdown: 'exports-loader?Dropdown!bootstrap/js/dist/dropdown',
            mapboxgl: 'mapbox-gl'
        })
    ]
};
View Code

4. 修改 /http/app.js 文件

'use strict';
var angular = require('angular');
var uirouter = require('angular-ui-router');

var css = require('./css/index.css');
var scss = require('./scss/index.scss');

var services = require('./services');
var directives = require('./directives');
var controllers = require('./controllers');
var views = require('./views');

var mapboxglDirective = 'mapboxgl-directive';

angular.module('wabgApp', [uirouter.default, services.default, views.default, directives.default, controllers.default, mapboxglDirective])
    .config(function ($stateProvider) {
        $stateProvider
            .state('home', {

            })
            .state('about', {
                url: '/about',
                controller: controllers.aboutController,
                templateUrl: views.about
            })
            .state('map', {
                url: '/map',
                controller: controllers.mapController,
                templateUrl: views.map
            });
    })
    .run([function () {
        mapboxgl.accessToken = true;
    }]);
View Code

5. 修改 /http/services/index.js 文件

'use strict';
var angular = require('angular');

var defaultMapStyle = require('./map-styles/default-style');

var servicesModule = angular.module('wabgApp.services', [])
    .constant(defaultMapStyle.name, defaultMapStyle());

exports = module.exports = {
    default: servicesModule.name
};
View Code

6. 创建 /http/services/map-styles/default-style.js 文件

'use strict';

function defaultMapStyle() {
    return {
        'version': 8,
        'sources': {
            'raster-tiles': {
                type: 'raster',
                'tiles': ['http://mt3.google.cn/vt/lyrs=s&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}'],
                'tileSize': 256
            }
        },
        'layers': [{
            'id': 'simple-tiles',
            'type': 'raster',
            'source': 'raster-tiles',
            'minzoom': 0,
            'maxzoom': 22
        }]
    };
}

exports = module.exports = defaultMapStyle;
View Code

7. 修改 /http/controllers/index.js 文件

'use strict';
var angular = require('angular');

var homeController = require('./home/home.controller');
var mapController = require('./map/map.controller');
var aboutController = require('./about/about.controller');

var controllersModule = angular.module('wabgApp.controllers', [])
    .controller(homeController.name, ['$scope', homeController])
    .controller(mapController.name, ['$scope', 'defaultMapStyle', mapController])
    .controller(aboutController.name, ['$scope', aboutController]);

exports = module.exports = {
    default: controllersModule.name,
    homeController: homeController.name,
    mapController: mapController.name,
    aboutController: aboutController.name
};
View Code

8. 创建 /http/controllers/map/map.controller.js 文件

'use strict';

function mapController($scope, defaultMapStyle) {
    $scope.glStyle = defaultMapStyle;
}

exports = module.exports = mapController;
View Code

9. 创建 /http/controllers/about/about.controller.js 文件

'use strict';

function aboutController($scope){
    $scope.text = 'webpack 3 + angularjs 1.* + bootstrap 4 + mapbox-gl demo';
}

exports = module.exports = aboutController;
View Code

10. 修改 /http/views/index.js 文件

'use strict';
var angular = require('angular');

function views() {
    return {
        demo: require('./demo/demo.view.html'),
        menu: require('./menu/menu.view.html'),
        map: require('./map/map.view.html'),
        about: require('./about/about.view.html')
    };
}

exports = module.exports = views();

var viewsModule = angular.module('wabgApp.views', [])
    .constant(views.name, exports);

exports.default = viewsModule.name;
View Code

11. 修改 /http/views/menu/menu.view.html 文件

<nav class="navbar navbar-light bg-light justify-content-between">
  <a class="navbar-brand" href="" ui-sref="map">Map</a>
  <a class="navbar-brand" href="" ui-sref="about">About</a>
  <form class="form-inline">
    <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
    <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
  </form>
</nav>
View Code

12. 创建 /http/views/map/map.view.html 文件

<div>
    <div mapboxgl gl-controls="glControls" gl-style="glStyle"></div>
</div>
View Code

13. 创建 /http/views/about/about.view.html 文件

<br />
<div style="font-weight:bold;font-size:18px">About: {{text}}</div>
View Code

14. 修改 /http/templates/index.tmpl.html 文件

<!DOCTYPE html>
<html ng-app="wabgApp">

<head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
    <style>
        .ng-cloak {
            display: none;
        }
    </style>
</head>

<body>
    <div id="root" ng-controller="homeController">
        <menu-directive></menu-directive>
        The Author is:
        <lable ng-ng-cloak class="ng-cloak" style="color:red">{{author}}</lable><br/>
        <input type="button" ng-click="getAuthor(name)" value="getAuthor" />
        <br/>
        <br/>
        <demo-directive></demo-directive>
        <ui-view></ui-view>
    </div>
</body>

</html>
View Code

15. 创建 /http/css/index.css 文件

@import '~mapbox-gl/dist/mapbox-gl.css';
@import '~angular-mapboxgl-directive/dist/angular-mapboxgl-directive.css';
View Code

16. 运行 npm run server 查看效果

 

 源码分享地址:https://gitee.com/think8848/wabg.git

posted on 2017-10-05 15:14  think8848  阅读(2949)  评论(0编辑  收藏  举报