在使用 babel 和 grunt 时,我遇到了 IE11 的一些问题。我需要使用一位前同事编写的新 ECMA 功能来填充一些代码,他将 babel 更新到 7.4(但没有将 babelrc 更改为使用 corejs),并且代码在 IE11 中不是 testet。所以现在代码在 Internet Explorer 中不起作用,我不得不填充,没有更深入的 babel 和 grunt 知识。我将 babelrc preset-env 更改为使用 builtIns,但无法使其运行。
我将 babelrc 更改为使用带有 builtIns 的预设环境。所以我将 useBuiltIns 设置为使用,所以 polyfills 仅在需要时包含。但随后 babel 会生成“require”语句,这些语句当然不能被浏览器解释。即使我将 useBuiltIns 设置为“entry”(而且我不知道与“usage”有什么区别),我在 IE11 的 js 控制台中得到“SCRIPT5009:“Symbol”未定义”作为错误。
package.json:
{
"name": "xyproject",
"version": "1.0.0",
"dependencies": {
"bootstrap3-dialog": "^1.35.4",
"core-js": "^3.1.4",
"datatables.net-bs": "^1.10.19",
"datatables.net-buttons-bs": "^1.5.6",
"datatables.net-colreorder-bs": "^1.5.1",
"datatables.net-responsive": "^2.2.3",
"datatables.net-responsive-bs": "^2.2.3",
"normalize-scss": "^7.0.1"
},
"devDependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-transform-object-assign": "^7.2.0",
"@babel/preset-env": "^7.5.5",
"babel-preset-minify": "^0.5.0",
"grunt": "^1.0.4",
"grunt-babel": "^8.0.0",
"grunt-concurrent": "^2.3.1",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-compass": "^1.1.1",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-sass": "^1.0.0",
"grunt-contrib-uglify": "^3.4.0",
"grunt-contrib-uglify-es": "^3.3.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-newer": "^1.3.0",
"grunt-notify": "^0.4.5",
"jit-grunt": "^0.10.0",
"time-grunt": "^1.4.0",
"uglify-es": "github:mishoo/UglifyJS2#harmony"
}
}
.babelrc:
{
"sourceType": "unambiguous",
"sourceMap": true,
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-template-literals",
"@babel/plugin-transform-object-assign"
],
"presets": [
[
"@babel/preset-env", {
"debug": false,
"useBuiltIns": "usage",
"corejs": 3,
"targets": {
"ie": "9"
}
}
],
[
"minify", {
"mangle": true,
"deadcode": true,
"simplify": true,
"builtIns": false
}
]
]
}
gruntfile.js:
'use strict';
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('../../package.json'),
config: {
sass: 'assets/scss',
css: 'assets/css',
js: 'assets/js',
templates: 'assets/templates',
build: 'assets/build',
node_modules: 'node_modules'
},
// notify if process is done
notify: {
watch_js: {
options: {
title: 'Task Complete',
message: 'JS Tasks are completed'
}
},
watch_css: {
options: {
title: 'Task Complete',
message: 'SCSS/CSS Tasks are completed'
}
}
},
// Bablify our js files - we're now able
// to write JS code in newest style :)
// Babel will transpile the code for elder browsers
babel: {
options: {
// babelrc: false,
// sourceType: 'unambiguous',
// sourceMap: true,
// presets: [
// [
// '@babel/preset-env', {
// targets: {
// ie: '9'
// }
// },
// ],
// [
// 'minify', {
// mangle: true,
// deadcode: true,
// simplify: true,
// // evaluate: true
// }
// ]
// ],
},
dist: {
files: {
'<%= config.build %>/backend.min.js': '<%= config.build %>/backend.min.js',
'<%= config.build %>/backend_tables.min.js': '<%= config.build %>/backend_tables.min.js',
'<%= config.build %>/backend_pages.min.js': '<%= config.build %>/backend_pages.min.js',
'<%= config.build %>/wysiwyg.min.js': '<%= config.build %>/wysiwyg.min.js',
'<%= config.build %>/dataview.min.js': '<%= config.build %>/dataview.min.js',
'<%= config.build %>/reporting.min.js': '<%= config.build %>/reporting.min.js',
// '<%= config.build %>/search.min.js': '<%= config.build %>/search.min.js',
}
}
},
build: {
clean: {
tasks: ['clean']
},
css: {
tasks: ['sass']
},
js: {
tasks: [
'concat',
'babel',
'uglify',
'remove_unnecessary_files'
]
}
},
// removes all files from folder
clean: ['<%= config.build %>/'],
// compiles scss to css
sass: {
dist: {
options: {
style: 'compressed',
compass: false,
loadPath: [
'node_modules/normalize-scss/sass'
]
},
files: {
'<%= config.build %>/main.css': [
'<%= config.sass %>/main.scss',
'<%= config.node_modules %>/bootstrap3-dialog/src/css/bootstrap-dialog.css'
]
}
}
},
concat: {
options: {
sourceMap: true
},
libs: {
src: [
'<%= config.node_modules %>/@babel/polyfill/dist/polyfill.min.js',
'<%= config.js %>/libs/jquery.min.js',
'<%= config.js %>/libs/jquery-ui.min.js',
'<%= config.js %>/libs/jquery.validate.js',
// bootstrap-4.1.3-dist/js/bootstrap.bundle.js
// '<%= config.js %>/bootstrap-4.1.3-dist/js/bootstrap.js',
// '<%= config.js %>/bootstrap-4.1.3-dist/js/bootstrap.bundle.js',
'<%= config.js %>/libs/bootstrap.min.js',
'<%= config.js %>/libs/bootstrap-select.js',
'<%= config.js %>/libs/bootstrap-datepicker.js',
'<%= config.js %>/libs/bootstrap-tagsinput.js',
'<%= config.js %>/libs/jquery.mCustomScrollbar.min.js',
'<%= config.js %>/libs/icheck.min.js',
// '<%= config.js %>/libs/jquery.tagsinput.min.js',
'<%= config.js %>/libs/jquery.noty.js',
'<%= config.js %>/libs/noty-layouts/topRight.js',
'<%= config.js %>/libs/noty-themes/default.js',
'<%= config.js %>/libs/jquery.nestable.js',
'<%= config.js %>/libs/fileinput.min.js',
'<%= config.js %>/libs/moment.min.js',
'<%= config.js %>/libs/plugins.js',
'<%= config.js %>/libs/actions.js',
'<%= config.js %>/libs/jquery.cookie.js',
'<%= config.js %>/libs/spin.min.js',
'<%= config.js %>/libs/select2.js',
'<%= config.js %>/libs/icheck_custom.js',
'<%= config.js %>/libs/bootstrap-typeahead.min.js',
'<%= config.js %>/libs/daterangepicker.js',
// if you want to add Datatatables plugins, see the following lines on how to do so:
// '<%= config.js %>/libs/datatables.js',
'<%= config.node_modules %>/datatables.net/js/jquery.dataTables.js',
'<%= config.node_modules %>/datatables.net-bs/js/dataTables.bootstrap.js',
'<%= config.node_modules %>/datatables.net-buttons/js/dataTables.buttons.js',
'<%= config.node_modules %>/datatables.net-buttons/js/buttons.colVis.js',
'<%= config.node_modules %>/datatables.net-buttons-bs/js/buttons.bootstrap.js',
'<%= config.node_modules %>/datatables.net-colreorder/js/dataTables.colReorder.js',
'<%= config.node_modules %>/datatables.net-responsive/js/dataTables.responsive.js',
'<%= config.node_modules %>/datatables.net-responsive-bs/js/responsive.bootstrap.js',
'<%= config.node_modules %>/bootstrap3-dialog/src/js/bootstrap-dialog.js',
'<%= config.js %>/libs/lodash.min.js',
'<%= config.js %>/libs/filesaver.js',
'<%= config.js %>/libs/queue.js',
],
dest: '<%= config.build %>/libs.min.js'
},
backend: {
src: [
'<%= config.js %>/globals.js',
'<%= config.js %>/backend.js',
'<%= config.js %>/datatable.js',
'<%= config.js %>/action.js',
'<%= config.js %>/menu.js',
'<%= config.js %>/validate.js',
'<%= config.js %>/ajax.js',
'<%= config.js %>/adv_search.js',
'<%= config.js %>/massupdate.js',
'<%= config.js %>/storage.js',
'<%= config.js %>/widgets.js',
'<%= config.js %>/sessionTimer.js',
'<%= config.js %>/widgets.js',
'<%= config.js %>/impersonate.js',
'<%= config.js %>/helper/*.js'
],
dest: '<%= config.build %>/backend.min.js'
},
pages: {
src: [
'<%= config.js %>/page_*.js',
],
dest: '<%= config.build %>/backend_pages.min.js'
},
dataview: {
src: [
'<%= config.js %>/dataview/*.js',
],
dest: '<%= config.build %>/dataview.min.js'
},
reporting: {
src: [
'<%= config.js %>/reporting/*.js',
],
dest: '<%= config.build %>/reporting.min.js'
},
tables: {
src: [
'<%= config.js %>/table_*.js',
'<%= config.js %>/table_search/type_base.js',
'<%= config.js %>/table_search/*.js',
],
dest: '<%= config.build %>/backend_tables.min.js'
},
/*search: {
src: [
// '<%= config.js %>/table_*.js',
'<%= config.js %>/table_search/*.js',
],
dest: '<%= config.build %>/search.min.js'
},*/
wysiwyg: {
src: [
'<%= config.js %>/wysiwyg.js',
],
dest: '<%= config.build %>/wysiwyg.min.js'
}
},
watch: {
options: {
spawn: false // add spawn option in watch task
},
css: {
files: [
'<%= config.sass %>/*.scss',
'<%= config.sass %>/*/**'
],
tasks: [
'sass',
'notify:watch_css'
]
},
devIe: {
files: [
'<%= config.js %>/*.js',
'<%= config.js %>/*/**'
],
tasks: [
'concat',
'babel',
'notify:watch_js'
]
},
js_dev: {
files: [
'<%= config.js %>/*.js',
'<%= config.js %>/*/**'
],
tasks: [
'concat',
// 'babel',
// 'rename_js_files',
'notify:watch_js'
]
},
livereload: {
options: {
livereload: true
},
files: ['<%= config.build %>**/*.js', '<%= config.build %>/main.css']
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + '<%= grunt.template.today("yyyy-mm-dd") %> */',
sourceMap: {
includeSources: true
},
report: 'gzip',
output: {
comments: false
},
sourceMapIn: function(path) {
return path + '.map';
}
},
dist: {
files: {
'<%= config.build %>/libs.min.js': ['<%= config.build %>/libs.min.js'],
'<%= config.build %>/backend.min.js': ['<%= config.build %>/backend.min.js'],
'<%= config.build %>/backend_tables.min.js': ['<%= config.build %>/backend_tables.min.js'],
'<%= config.build %>/backend_pages.min.js': ['<%= config.build %>/backend_pages.min.js'],
'<%= config.build %>/wysiwyg.min.js': '<%= config.build %>/wysiwyg.min.js',
'<%= config.build %>/dataview.min.js': ['<%= config.build %>/dataview.min.js'],
'<%= config.build %>/reporting.min.js': ['<%= config.build %>/reporting.min.js'],
'<%= config.build %>/search.min.js': ['<%= config.build %>/search.min.js'],
}
}
},
concurrent: {
options: {
logConcurrentOutput: true
},
dev: {
tasks: ['watch:js_dev', 'watch:css', 'watch:livereload']
// tasks: ['watch:js_dev', 'watch:css']
},
devIe: {
tasks: ['watch:devIe', 'watch:css']
// tasks: ['watch:js_dev', 'watch:css']
}
}
});
// grunt.loadNpmTasks('grunt-contrib-sass');
// grunt.loadNpmTasks('grunt-contrib-watch');
// grunt.loadNpmTasks('grunt-contrib-concat');
// grunt.loadNpmTasks('grunt-contrib-uglify');
// grunt.loadNpmTasks('grunt-contrib-handlebars');
// grunt.loadNpmTasks('grunt-notify');
// grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-uglify-es');
grunt.registerMultiTask('build', 'build the given task', function() {
grunt.task.run( this.data.tasks );
});
grunt.registerTask('remove_unnecessary_files', 'Remove *.js to *.min.js', () => {
let fs,
fileNames,
fileName;
fs = require('fs');
fileNames = [
'backend_tables.js',
'backend_tables.js.map',
'backend_tables.min.js.map',
'backend.js',
'backend.js.map',
'backend.min.js.map',
'backend_pages.js',
'backend_pages.js.map',
'backend_pages.min.js.map',
'libs.js',
'libs.js.map',
'libs.min.js.map',
'main.css.map'
];
for (fileName in fileNames) {
if (fs.existsSync(grunt.config.data.config.build + '/' + fileNames[fileName])) {
fs.unlink(grunt.config.data.config.build + '/' + fileNames[fileName], (err) => {
if (err) {
grunt.log.error(`Remove ${grunt.config.data.config.build + '/' + fileNames[fileName]} failed: ${err}`);
} else {
grunt.log.ok(`Remove ${grunt.config.data.config.build + '/' + fileNames[fileName]} done`);
}
});
}
}
});
grunt.registerTask('rename_js_files', 'Rename *.js to *.min.js', function() {
var fs,
libsFileName,
libsMinFileName,
backendFileName,
backendMinFileName;
fs = require('fs');
libsFileName = grunt.config.data.config.build + '/libs.js';
libsMinFileName = grunt.config.data.config.build + '/libs.min.js';
backendFileName = grunt.config.data.config.build + '/backend.js';
backendMinFileName = grunt.config.data.config.build + '/backend.min.js';
fs.rename(libsFileName, libsMinFileName, function(err) {
if (err) {
grunt.log.error('ERROR: ' + err);
}
});
fs.rename(backendFileName, backendMinFileName, function(err) {
if (err) {
grunt.log.error('ERROR: ' + err);
}
});
});
// grunt.registerTask('default', ['build', 'watch:css', 'watch:js']);
grunt.registerTask('watch:dev', ['build', 'concurrent:dev']);
// grunt.registerTask('watch:dev-ie', ['build', 'concurrent:devIe']);
grunt.registerTask('watch:dev-ie', ['watch:devIe', 'watch:css', 'watch:livereload']);
require('jit-grunt')(grunt);
};
我正在使用“./node_modules/.bin/grunt watch:dev-ie”运行应用程序,然后更改一些 javascript 代码以触发 livereload,因此执行“devIe”任务并且 babel 将转译代码。如果我在 babelrc 代码中使用“条目”作为 useBuiltIn 选项的值,但我得到“符号未定义”。当我使用“usage”作为值时,babel 将 require 语句添加到我缩小的 js 文件中,我在 js 控制台中得到“require is undefined”。
我用 IE11 测试代码。我不想使用 Browserify 或 webpack,因为这会使事情变得更复杂。谁能告诉我我的配置中缺少什么以使事情正常进行?我原以为 babel 不会创建现代浏览器无法解释的 require 语句,需要由 webpack 或其他东西翻译才能使事情正常运行。我只想扩展我的 babel / grunt 配置来填充 javascript 代码以在 IE11 中工作。也许我在 package.json 中也缺少一个包?