Как использовать полифилы с бабел 7.4 и хрюкать?
Я столкнулся с несколькими проблемами с IE11 при использовании babel и grunt. Мне нужно заполнить некоторый код, используя новые функции ECMA, написанные бывшим коллегой, который обновил babel до 7.4 (но не изменил babelrc для использования corejs), и код не тестировался в IE11. Так что теперь код не работает в Internet Explorer, и мне пришлось многократно заполнять, не имея глубоких знаний о babel и grunt. Я изменяю babelrc preset-env для использования встроенных функций, но не могу запустить его.
Я изменяю babelrc для использования preset-env со встроенными. Поэтому я установил useBuiltIns на использование, поэтому полифилы включаются только при необходимости. Но затем babel генерирует операторы "require", которые, конечно, не могут быть интерпретированы браузерами. Даже когда я устанавливаю для useBuiltIns значение "entry" (и я понятия не имею, в чем отличие от "use"), я получаю "SCRIPT5009: "Symbol"не определен" как ошибку в консоли js в моем IE11.
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 будет передавать код. Если я использую "запись" в качестве значения для параметра useBuiltIn в коде babelrc, работает, но я получаю "символ не определен". Когда я использую "использование" в качестве значения, тогда babel добавляет операторы require в мои минимизированные js-файлы, и я получаю "require is undefined" в консоли js.
Я тестирую код с IE11. Я не хочу использовать Browserify или веб-пакет, поскольку это усложнит ситуацию. Может кто-нибудь сказать мне, что мне не хватает в моих конфигах, чтобы заставить вещи работать? Я бы ожидал, что babel не создает операторы require, которые не могут быть интерпретированы современными браузерами и должны быть переведены через веб-пакет или что-то еще, чтобы заставить вещи работать. Я просто хочу расширить мою конфигурацию babel / grunt, чтобы заполнить код javascript для работы в IE11. Может быть, мне также не хватает пакета в package.json?