Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

从angular1.x到angular2的一点实践(updated:2016-12-12) #1

Open
leopen-hu opened this issue Nov 26, 2016 · 2 comments
Open
Assignees

Comments

@leopen-hu
Copy link
Owner

leopen-hu commented Nov 26, 2016

从angular1.x到angular2的一点实践

更新

  • (2016-12-12)gulp工具流支持ES5和ES6同时翻译——兼顾新老代码

项目原状

  • angular1.3,不支持component
  • 没有使用CommJS/CMD/AMD等模块化方式
  • 使用ES5

项目预期

  • 使用ES6(是否使用TypeScript待评估)
  • 模块化(支持ES6的importexport
  • angular1.x升级至angular2

项目实践(不敢步子迈得太大)

  • 从ES5到ES6
    • 引入babel到gulp工作流 。将后缀为.es6.js的文件在原目录下翻译成ES5格式的.js文件,运行或打包时忽略.es6.js文件;由于babel转义模块化会使用CommonJS,但是对于这一块的打包目前还没有怎么研究,所以暂时使用这种不彻底的方式,下文的代码是我同事所撸,对于gulp我还不是很熟;
    'use strict';
    const gulp = require('gulp');
    const babel = require('gulp-babel');
    const path = require('path');
    const conf = require('./conf');
    const rename = require("gulp-rename");
    gulp.task('babel', () => {
      return gulp.src([
        path.join(conf.paths.src, '/**/*.es6.js'),
        '!' + path.join(conf.paths.src, '/**/imports/**/*.es6.js')
      ])
      .pipe(rename(function(path) {
        path.basename = path.basename.replace(/\.es6/, '');
      }))
      .pipe(babel({
        presets: ['es2015'],
        plugins: [
          'external-helpers',
      ]}))
      .pipe(gulp.dest(conf.paths.src));
    });
    • 新的feature使用ES6语言开发,原有文件涉及改动时考虑重新使用ES6编写(暂不引入模块化),下以service为例,controller等类似,可以参考民工叔叔的博文《Angular 1.x和ES6的结合》
    class VideoPlayerService {
      constructor($sce) {
        this.$http= $http;
        this.videoConfig = {
          showVideoPlayer: false,
          videoUrl: null
        };
      }
    
      post() {
        this.$http.post('url', data: {}})
          .then(resp => resp.data, err => err);
      }
    }
    
    VideoPlayerService.$inject = ['$http'];
    
    angular.module('vwmsApp.newbieGuideModule')
      .service('videoPlayerService', VideoPlayerService);
  • 引入模块化
    正在和同事考虑使用browserfy或webpack来把require在打包的时候编译掉,这样就可以引入ES6的模块化了,把对于Angular1.x的依赖全部迁移到module文件中去。
  • 迁移到angular2
    这个估计需要一段时间,在前面实现的基础上,还要对template的代码进行改造,甚至一些自定义组件也还要花比较多的时间。在目前业务实现还有很多的情况下,只能循序渐进
@leopen-hu leopen-hu self-assigned this Dec 22, 2016
@leopen-hu
Copy link
Owner Author

leopen-hu commented Dec 22, 2016

(2016-12-12)gulp工具流支持ES5和ES6同时翻译——兼顾新老代码

  • 基于generator-gulp-angular这个项目的ES5和ES6整合,原项目没有使用require,也不打算引入require

  • 主要思路:

    • 先使用babel翻译ES6,
    • 使用webpack打包屏蔽require带来的影响,
    • inject编译后的代码到html,
    • 生产打包,测试的原理与dev调试相同。
  • 时间有限,主要代码如下:

function webpackWrapper(watch, test, callback) {
    var webpackOptions = {
        watch: watch,
        module: {
            // 注释是因为要同时支持ES5和ES6,目前没有研究这个怎么配置格式化文件
            // preLoaders: [{ test: /\.js$/, exclude: /node_modules/, loader: 'eslint-loader' }],
            loaders: [{ test: /\.js$/, exclude: /node_modules/, loaders: ['babel-loader?presets[]=es2015'] }]
        },
        output: { filename: 'index.module.js' }
    };

    if (watch) {
        webpackOptions.devtool = 'inline-source-map';
    }

    var webpackChangeHandler = function(err, stats) {
        if (err) {
            conf.errorHandler('Webpack')(err);
        }
        $.util.log(stats.toString({
            colors: $.util.colors.supportsColor,
            chunks: false,
            hash: false,
            version: false
        }));
        browserSync.reload();
        if (watch) {
            watch = false;
            callback();
        }
    };

    var sources = [
        path.join(conf.paths.src, '/app/**/*.js'),
        path.join('!' + conf.paths.src, '/app/**/lodop_print_template/js_templates/**/*.js'),
        path.join('!' + conf.paths.src, '/app/**/*.mock.js'),
        path.join('!' + conf.paths.src, '/app/**/*.e2e.js'),
        path.join('!' + conf.paths.src, '/app/data/*.js')
    ];


    if (!test) {
        sources = sources.concat([
            path.join('!' + conf.paths.src, '/app/**/*.spec.js'),
            path.join('!' + conf.paths.src, '/app/**/*.spec.es6.js')
        ]);
    }

    return gulp.src(sources)
        .pipe($.babel({
            presets: ['es2015'],
            plugins: [
                'external-helpers',
            ]
        }))
        // 下一步很重要,对angular文件进行排序
        .pipe($.angularFilesort()).on('error', conf.errorHandler('AngularFilesort'))
        .pipe(webpack(webpackOptions, null, webpackChangeHandler))
        .pipe(gulp.dest(path.join(conf.paths.tmp, '/serve/app')));
}

gulp.task('scripts', function() {
    return webpackWrapper(false, false);
});

gulp.task('scripts:watch', ['scripts'], function(callback) {
    return webpackWrapper(true, false, callback);
});

gulp.task('scripts:test', function() {
    return webpackWrapper(false, true);
});

gulp.task('scripts:test-watch', ['scripts'], function(callback) {
    return webpackWrapper(true, true, callback);
});
gulp.task('inject', ['scripts', 'styles'], function() {
    var injectStyles = gulp.src([
        path.join(conf.paths.tmp, '/serve/app/**/*.css'),
        path.join(conf.paths.src, '/css/*.css'),
        path.join('!' + conf.paths.tmp, '/serve/app/vendor.css')
    ], { read: false });

    var injectScripts = gulp.src([
        path.join(conf.paths.tmp, '/serve/app/**/*.module.js')
    ], { read: false });

    var injectOptions = {
        ignorePath: [conf.paths.src, path.join(conf.paths.tmp, '/serve')],
        addRootSlash: false
    };

    return gulp.src(path.join(conf.paths.src, '/*.html'))
        .pipe($.inject(injectStyles, injectOptions))
        .pipe($.inject(injectScripts, injectOptions))
        .pipe(wiredep(_.extend({}, conf.wiredep)))
        .pipe(gulp.dest(path.join(conf.paths.tmp, '/serve')));
});
  • 遇到坑及解决办法:

    • 注入错误(混淆代码后),大部分是因为没有$injector;
    • 测试module()方法报错,解决办法:因为module方法不再全局,使用angular.mock.module();
    • 第三方库报错,解决方法:1.自己改写(好麻烦); 2.使用(function(global)())(typeof global === "undefined" ? self : global)包裹;
  • 欢迎大家来讨论如何让老代码和新代码共存的情况下更清晰合理。

@leopen-hu leopen-hu changed the title 从angular1.x到angular2的一点实践 从angular1.x到angular2的一点实践(update:2016-12-12) Dec 22, 2016
@leopen-hu leopen-hu changed the title 从angular1.x到angular2的一点实践(update:2016-12-12) 从angular1.x到angular2的一点实践(updated:2016-12-12) Dec 22, 2016
@leopen-hu
Copy link
Owner Author

leopen-hu commented Dec 21, 2017

目前已从原公司离职,本文基本没有续更可能。

@leopen-hu leopen-hu reopened this Dec 26, 2017
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant