Karma + Webpack(babel-loader)+ ES6“意外令牌导入” [英] Karma + Webpack (babel-loader) + ES6 "Unexpected token import"

查看:201
本文介绍了Karma + Webpack(babel-loader)+ ES6“意外令牌导入”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

/ edit:我将配置完全删除到最小程度来证明问题。我还向GitHub上传了一个工作项目,您可以检查出来,以便您可以自己查看。



GitHub上有问题的用例:webpack-angular15-es6-karma download 7z archive

  npm install 
npm run build
npm run test






我知道有几个相关的问题,但世界正在如此之快,有这么多因素/依赖关系,我无法解决当前提出的解决方案的这个问题。 p>

我有一个webpack配置来处理所有的源代码,它的工作原理很好。



对于测试,我重新使用该配置来处理加载源和测试文件的单个中央条目脚本。我找不到另一种方式将模块从我的源代码导入我的测试代码进行测试。



Karma构建良好的重用我的webpack配置,但浏览器报告一旦它被打开就会出现错误。



源代码使用ES6导入和webpack require语句。



package.json


npm运行构建>>> webpack --config webpack.config .js --display-error-details --colors --progress



npm run test >>> karma start --single-run --no-auto-watch karma.config.js




  {
name:ProblemDemo
scripts:{
build:rimraf dist&& webpack --config webpack.config.js --display-error-details --colors --progress,
test:karma start --single-run --no-auto-watch karma.config.js
},
dependencies:{
angular: ^ 1.5.7,
角过滤器:^ 0.5.8
},
devDependencies:{
webpack:1.13.1,
html-loader:0.4.3,
babel-loader :5.3.2,
html-webpack-plugin:1.6.1,
rimraf:^ 2.5.3,
run-sequence :1.1.2,
jasmine-core:^ 2.4.1,
karma:^ 0.13.19,
karma-chrome-launcher :^ 0.2.2,
karma-coverage:^ 0.5.3,
karma-jasmine:^ 0.3.6,
karma-webpack :^ 1.7.0,
loader-utils:^ 0.2.12
}
}

karma.config.js:

  module.exports = function(config){
config.set({
browsers:['Chrome'],
coverageReporter:{
reporters:[
{类型:'html',subdir:'html'},
{type:'lcovonly',subdir:'。'}
]
},
文件:['。 /tests.webpack.js'],
框架:['jasmine'],
preprocessors:{'./tests.webpack.js':['webpack']},
记者:['progress','coverage'],
webpack:configureWebpack()
});

函数configureWebpack(webpackConfigFunction){
var webpackConfig = require('./ webpack.config');
webpackConfig.entry = undefined; // karma将通过正确的参数
return webpackConfig;
}
};

正如你所看到的,我没有使用karma-babel插件:我不知道为什么我将需要这些,看到我已经有一个工作的代码与import / require语句的代码。



test_entry.js:

  var testsContext = require.context('./ test',true,/\.js$/); 
testsContext.keys()。forEach(testsContext);

var srcContext = require.context('./ app',true,/\.js$/);
srcContext.keys()。forEach(srcContext);






Webpack构建成功没有挂钩(并发出 test_entry.js 预期文件大小的块),但是随后Karma打开Chrome,一旦页面加载,我遇到以下错误:


Chrome 51.0.2704(Windows 7 0.0.0)错误



未捕获SyntaxError:意外的令牌导入



at_path / test_entry.js:41


test_entry.js 没有41行,不包含导入语句,反正应该被照顾。发生什么事?



如果您想知道webpack配置:



  // webpack.config.js,适用于正常构建,但不适用于Karmavar path = require('path'); var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = {debug:true,entry:{app:['./app/index.js'],vendor: './app/vendor.js']},输出:{path:path.join(__ dirname,'dist'),filename:'js / [name] .js'},插件:[new HtmlWebpackPlugin({template: './app/index.html',注:'body',minify:false}),新的webpack.optimize.CommonsChunkPlugin('vendor','js / vendor.js'),新的webpack.SourceMapDevToolPlugin({filename: '[file] .map',exclude:/ vendor /})],res olve:{extensions:['','.js'],别名:{app:path.join(__ dirname,'app')}},module:{loaders:[{test:/\sjs/ loader:'babel-loader',包括:path.join(__ dirname,'app'),exclude:path.join(__ dirname,'node_modules')},{test:/\.html$/,loader:'html -loader'}]},resolveLoader:{root:path.join(__ dirname,'node_modules')},};  

p>

如果你想看到我的测试,由 test_entry.js 要求,我无法运行:



 从'jasmine-core'导入jasmine;从./file_path导入可读的NumberFilter /readableNumber.filter'////由于某些原因需要,否则意外的令牌错误在构建期间:var describe = jasmine.describe ; var it = jasmine.it; var expect = jasmine.expect; describe('readableNumber Filter',function(){describe('readableNumber Filter formatting',()=> {it('它应该支持可选参数',function(){expect(可读数字过滤器(50.3))toEqual(50,30);}); });});  






编辑20-7-2016



还有更新的babel-loader依赖关系的问题依然存在(包括设置es2015预设选项) 。 babel-core:^ 6.11.4,babel-loader:^ 6.2.4,babel-preset-es2015:^ 6.9.0,

解决方案

问题是你没有透露你的测试源 - 文件 src / global / filters / dateFormat.filter.spec.js 没有被折腾。



您需要更改此加载器配置:

  {
test:/\.js$/,
loader:'babel-loader',
include:path.join(__ dirname,'app'),
exclude:path.join(__ dirname,'node_modules')
},

如下,以使之正常工作:

  {
test:/\.js$/,
loader:'babel-loader',
include:[
path.join(__ dirname,'app'),
path.join(__ dirname,'test')
],
exclude:path.join(__ dirname,'node_modules')
},

还有一个问题, webpack.optimize.CommonsChunkPl ugin 插件 - 应该禁用因果报应:
https://github.com/webpack/karma-webpack/issues/22



禁用此插件后,测试文件中有错误:

 从'jasmine-core'导入茉莉花; 

import readNumberFilter from'readableNumber.filter';

var describe = jasmine.describe;
var it = jasmine.it;
var expect = jasmine.expect;

describe('readableNumber Filter',function(){
describe('readableNumber过滤器格式化',()=> {
它(它应该支持可选参数) ,function(){
expect(readableNumberFilter(50.3))toEqual(50,30);
});
});
});

此测试中几乎没有错误:



< $>
  • 从'jasmine-core'导入茉莉花; - 你不应该这样做(业务会做,也会添加描述 it expect

  • import visibleNumberFilter from'readableNumber.filter'; - 这不是你如何实例化角度服务,测试它们。

  • 你应该做这样的事情(这个测试实际上适用于上面提到的所有修复):

     从角度导入角度; 
    import'angular-mocks';

    从'../../../../app/src/global/index'导入testModule;

    const {module,inject} = angular.mock;

    describe('readableNumber Filter',()=> {
    beforeEach(module(testModule));

    让$ filter;

    beforeEach(inject(($ $ filter_)=> {
    $ filter = _ $ filter_;
    }));

    describe('可读数过滤格式' ,()=> {
    it('它应该支持可选参数',()=> {
    const result = $ filter('可读数)'(50.3);
    expect(result).toEqual(50,30);
    });
    });
    });

    注意:您需要安装模块 angular-mocks ;






    为了支持代码覆盖率报告,您将需要配置您测试webpack配置,使用类似巴别-伊斯坦布尔装载机。顺便说一下,您还需要升级到Babel6。



    此外,您还需要使webpack配置更加可配置(用于测试和生产的配置需要略有不同)。



    我已经向您发送了所有这些修复的拉式请求: https://github.com/bbottema/webpack-angular15-es6-karma/pull/1






    关于使用webpack构建角度1.x项目,包括通过业务进行代码覆盖的测试 - 也许您会对我的项目感兴趣: https://github.com/zxbodya/angular-webpack-seed - 它是具有所有必需配置的启动器模板。


    /edit: I stripped the config completely to a minimum demonstrating the problem. I also uploaded a working project to GitHub that you can checkout, so you can see for yourself.

    Problematic use case on GitHub: webpack-angular15-es6-karma (download 7z archive)

    npm install
    npm run build
    npm run test
    


    I know there are a couple of related questions, but the world is moving so fast and there are so many factors / dependencies that I'm not able to crack this problem with the current proposed solutions.

    I have a webpack config that takes care of all my source code and it works great.

    For testing, I reuse that config to take care of a single central entry script that loads both the sources and the test files. I could not find another way to import modules from my source code into my test code for testing.

    Karma builds fine reusing my webpack config, but the browser reports an error as soon as it is opened.

    The source code uses ES6 imports and webpack require statements.

    package.json:

    npm run build >>> webpack --config webpack.config.js --display-error-details --colors --progress

    npm run test >>> karma start --single-run --no-auto-watch karma.config.js

    {
      "name": "ProblemDemo",
      "scripts": {
        "build": "rimraf dist && webpack --config webpack.config.js --display-error-details --colors --progress",
        "test": "karma start --single-run --no-auto-watch karma.config.js"
      },
      "dependencies": {
        "angular": "^1.5.7",
        "angular-filter": "^0.5.8"
      },
      "devDependencies": {
          "webpack": "1.13.1",
          "html-loader": "0.4.3",
          "babel-loader": "5.3.2",
          "html-webpack-plugin": "1.6.1",
          "rimraf": "^2.5.3",
          "run-sequence": "1.1.2",
          "jasmine-core": "^2.4.1",
          "karma": "^0.13.19",
          "karma-chrome-launcher": "^0.2.2",
          "karma-coverage": "^0.5.3",
          "karma-jasmine": "^0.3.6",
          "karma-webpack": "^1.7.0",
          "loader-utils": "^0.2.12"
      }
    }
    

    karma.config.js:

    module.exports = function (config) {
        config.set({
            browsers: ['Chrome'],
            coverageReporter: {
                reporters: [
                    { type: 'html', subdir: 'html' },
                    { type: 'lcovonly', subdir: '.' }
                ]
            },
            files: ['./tests.webpack.js'],
            frameworks: ['jasmine'],
            preprocessors: { './tests.webpack.js': ['webpack'] },
            reporters: ['progress', 'coverage'],
            webpack: configureWebpack()
        });
    
        function configureWebpack(webpackConfigFunction) {
            var webpackConfig = require('./webpack.config');
            webpackConfig.entry = undefined; // karma will pass the proper argument for entry
            return webpackConfig;
        }
    };
    

    As you can see I'm not using karma-babel plugins: I'm not sure why I would need those, seeing I already have a working build for code with import / require statements.

    test_entry.js:

    var testsContext = require.context('./test', true, /\.js$/);
    testsContext.keys().forEach(testsContext);
    
    var srcContext = require.context('./app', true, /\.js$/);
    srcContext.keys().forEach(srcContext);
    


    The webpack build succeeds without a hitch (and emits test_entry.js chunk of expected file size), but then Karma opens Chrome and as soon as the page is loaded I'm greeted with the following error:

    Chrome 51.0.2704 (Windows 7 0.0.0) ERROR

    Uncaught SyntaxError: Unexpected token import

    at the_path/test_entry.js:41

    test_entry.js doesn't have 41 lines and doesn't contain import statements and anyway they should have been taken care of. What's going wrong?

    In case you want to know the webpack config as well:

    // webpack.config.js, works perfectly for normal builds but not with Karma
    var path = require('path');
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
    	debug: true,
    	entry: {
    		app: ['./app/index.js'],
    		vendor: ['./app/vendor.js']
    	},
    	output: {
    		path: path.join(__dirname, 'dist'),
    		filename: 'js/[name].js'
    	},
    	plugins: [
    		new HtmlWebpackPlugin({
    			template: './app/index.html',
    			inject: 'body',
    			minify: false
    		}),
    		new webpack.optimize.CommonsChunkPlugin('vendor', 'js/vendor.js'),
    		new webpack.SourceMapDevToolPlugin({
    			filename: '[file].map',
    			exclude: /vendor/
    		})
    	],
    	resolve: {
    		extensions: ['', '.js'],
    		alias: {
    			app: path.join(__dirname, 'app')
    		}
    	},
    	module: {
    		loaders: [
    			{
    				test: /\.js$/,
    				loader: 'babel-loader',
    				include: path.join(__dirname, 'app'),
    				exclude: path.join(__dirname, 'node_modules')
    			},
    			{
    				test: /\.html$/,
    				loader: 'html-loader'
    			}
    		]
    	},
    	resolveLoader: {
    		root: path.join(__dirname, 'node_modules')
    	},
    };

    In case you want to see my test, required by test_entry.js, which I can't get to run:

    import jasmine from 'jasmine-core';
    import readableNumberFilter from './file_path/readableNumber.filter';
    
    // for some reason needed, or else unexpected token errors during build:
    var describe = jasmine.describe;
    var it = jasmine.it;
    var expect = jasmine.expect;
    
    describe('readableNumber Filter', function () {
    	describe('readableNumber Filter formatting', () => {
    		it('it should support optional arguments', function () {
    			expect(readableNumberFilter("50.3")).toEqual("50,30");
    		});
    	});
    });


    edit 20-7-2016

    The problem persists with updated babel-loader dependencies as well (including setting es2015 presets option). "babel-core": "^6.11.4", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.9.0",

    解决方案

    The problem is that you are not transpiling you test sources - file src/global/filters/dateFormat.filter.spec.js was not transpiled.

    You need to change this loader config:

    {
        test: /\.js$/,
        loader: 'babel-loader',
        include: path.join(__dirname, 'app'),
        exclude: path.join(__dirname, 'node_modules')
    },
    

    As following, to make it work:

    {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [
            path.join(__dirname, 'app'),
            path.join(__dirname, 'test')
        ],
        exclude: path.join(__dirname, 'node_modules')
    },
    

    There is also issue with webpack.optimize.CommonsChunkPlugin plugin - it should be disabled for karma: https://github.com/webpack/karma-webpack/issues/22

    Than after disabling this plugin, there is mistakes in your test file:

    import jasmine from 'jasmine-core';
    
    import readableNumberFilter from 'readableNumber.filter';
    
    var describe = jasmine.describe;
    var it = jasmine.it;
    var expect = jasmine.expect;
    
    describe('readableNumber Filter', function () {
        describe('readableNumber Filter formatting', () => {
            it('it should support optional arguments', function () {
                expect(readableNumberFilter("50.3")).toEqual("50,30");
            });
        });
    });
    

    there is few errors in this test:

    1. import jasmine from 'jasmine-core'; - you should not do that (karma will do, also it will add describe, it and expect)
    2. import readableNumberFilter from 'readableNumber.filter'; - it is not the way how you can instantiate angular services, to test them.

    You should do something like, this(this test actually works with all fixes mentioned above):

    import angular from 'angular';
    import 'angular-mocks';
    
    import testModule from '../../../../app/src/global/index';
    
    const { module, inject } = angular.mock;
    
    describe('readableNumber Filter', () => {
        beforeEach(module(testModule));
    
        let $filter;
    
        beforeEach(inject((_$filter_) => {
            $filter = _$filter_;
        }));
    
        describe('readableNumber Filter formatting', () => {
            it('it should support optional arguments', () => {
                const result = $filter('readableNumber')("50.3");
                expect(result).toEqual("50,30");
            });
        });
    });
    

    Notice: you will need to install module angular-mocks;


    To support code coverage reporting you will need to configure you test webpack configuration to use something like babel-istanbul-loader. By the way you will also need to upgrade to Babel6.

    Also you will need to make webpack config more configurable(configurations for testing and production need do be slightly different).

    I have sent you a pull-request with all these fixes: https://github.com/bbottema/webpack-angular15-es6-karma/pull/1


    About building angular 1.x project with webpack, including testing with code coverage via karma - maybe you would be interested in my project: https://github.com/zxbodya/angular-webpack-seed - it is starter template with all required configurations.

    这篇关于Karma + Webpack(babel-loader)+ ES6“意外令牌导入”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆