Автор оригинала: Nicholas Arthur.
Есть много причин, по которым вы можете продолжать работать с Angularjs 1.x – я просто предположим, что у вас есть свои причины.
Угловые ≠ ангулярные. Этот сайт и все его содержимое относятся к Angularjs (версия 1.x), если вы ищете новейшие угловые, пожалуйста, посетите Angular.io – Angularjs.org
Для новых проектов я бы порекомендовал использовать React, потому что именно здесь импульс находится в предельном развитии.
2018 редактирование: Vuejs, кажется, где находится отрасль сейчас
Или, по крайней мере, этот человек думает, что это, и я согласен с ним
Я сделал репо Github, вы можете вилочные/клон, чтобы начать свой собственный проект
jsdoc_output // where docs are generated node_modules // where your vendor stuff goes .gitignore mocha-webpack.opts // specify a different webpack config for testing package.json README.md webpack.config.base.js webpack.config.js // extends base config webpack.config.test.js // extends base config public | index-bundle.js // webpack generated bundle | index.html | index.js // webpack | \---superAwesomeComponent componentStylez.sass componentTemplate.html fancyJsModule.js theComponent.js theComponent.spec.js theComponentController.js
Генерируется с использованием дерева/A/F в Windows
Давайте проверим index.html.
A variable on the controller above the components: {{IndexCtrl.fancyValue}}
Ни одно действие еще не было сделано
Здесь вы можете увидеть, что наши две кнопки являются двумя супер-удивительными элементами. Это угловые 1,5 компонента.
Угловые 1,5 компонента
Угловые 1.5 компоненты – это просто директивы с лучшими значениями по умолчанию. Они всегда элементы, есть контроллер по умолчанию, как $ Ctrl », и у них есть изолирующие области. Большинство из того, что я узнал о компонентах, я узнал их здесь Отказ
Компоненты имеют два привязки, Некоторые ввод и Некоторые вывод Отказ
Эти компоненты полезны, потому что они позволяют нам инкапсулировать комбинацию функциональности просмотра и контроллера. Давайте посмотрим на компонентный файл:
import template from './componentTemplate.html' import componentStylez from './componentStylez.sass' import {ComponentController} from './theComponentController.js' const bindings = { someInput: '<', someOutput: '&' } export const theComponent = { controller: ComponentController, template, bindings }
Обратите внимание, как каждый элемент контроллера можно повторно использовать. Контроллер может быть специфичным для этого компонента, или он может быть контроллером, который используется в другом месте.
Кроме того, этот файл содержит ссылки на Все, что вам нужно знать о компоненте. Компонент абсолютно состоит в том, что вам не нужно беспокоиться о том, как он используется в более крупном приложении, чтобы сделать его.
Контроллер использует нормальные функции ES6 – я не пойду в то, как он работает, но примите к сведению, как используется структура класса, а также отсутствие \ $ Case
Отказ Результатом является карточный агностический контроллер, минус Событие жизненного цикла компонента ( \ $ Oninit
) Отказ
import fancyFunction from './fancyJsModule.js' /** * Provides handlers for theComponent */ class ComponentController { /** * Announces that input bindings aren't defined * @return {undefined} undefined */ constructor () { console.log('input bindings arent defined!', this.someInput) } /** * Calls someOutput with the value of someInput put in fancyFunction * @return {undefined} undefined */ doSuperThings () { console.log('doing super things') this.someOutput({value: fancyFunction(this.someInput, 3)}) } /** * Announces that input bindings are defined * @return {undefined} undefined */ $onInit () { console.log('input bindings are defined!', this.someInput) } } export { ComponentController }
Форматирование стандартизации
Очевидная разница – отсутствие полукол. Я лично верю, что это обеспечивает более чистый код, и стандартный Linter/Formatter аккуратно решает проблемы вокруг использования запятой, что помешает вам столкнуться с странными проблемами.
WebPack (который может быть запутанным)
Обратите внимание, как все, что нам нужно сделать, это импортировать index.bundle.js
в index.html
Отказ Это потому, что мы используем WebPack, который связывает все наши активы в один файл. Это включает в себя наши шаблоны, JavaScript, CSS и все, что вы можете себе представить, нуждается в там.
WebPack – это финиковый зверь и зверь это. Это достаточно сложно, чтобы люди положили его на их резюме. Он перемещает много сложности из различных частей вашего приложения, в ваш webpack.config.js
файл.
Доказательства этой сложности можно найти в том, что у нас есть причина для 3 WebPack.config * .js
файлы. Один из них содержит основание, второй – разместить нашу настройку тестирования, а третий предназначен для расщепленного кода до кусочки поставщиков (которые мы не хотим делать в нашей настройке теста, выполняем странные взаимодействия с CommonschunkPlugplugin
) Отказ
var path = require('path') var webpack = require('webpack') module.exports = { entry: { 'index': path.join(__dirname, '/public/index.js') }, output: { filename: '[name]-bundle.js', path: path.join(__dirname, '/public/'), devtoolLineToLine: true, pathinfo: true, sourceMapFilename: '[name].js.map', publicPath: path.join(__dirname, '/src/main/webapp/') }, module: { loaders: [ { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.sass$/, loaders: ['style-loader', 'css-loader', 'sass-loader'] }, { test: /\.html$/, loader: 'raw-loader' }, // inline base64 URLs for <=8k images, direct URLs for the rest { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }, // helps to load bootstrap's css. { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&minetype=application/font-woff' }, { test: /\.woff2$/, loader: 'url?limit=10000&minetype=application/font-woff' }, { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&minetype=application/octet-stream' }, { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' }, { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&minetype=image/svg+xml' } ] }, plugins: [ new webpack.HotModuleReplacementPlugin() ], devServer: { publicPath: '/', contentBase: path.join(__dirname, '/public'), compress: true }, devtool: 'eval' }
Я не собираюсь объяснять все здесь, потому что это то, что WebPack Docs Для (эта ссылка предназначена для WebPack 1, даже если мы используем WebPack 2. Документы WebPack 2 тщательно тщательно в их неполноте, но видят документацию Migration ).
Чтобы дать обзор, вы должны указать:
- Где начинается ваше приложение
- Где идет пучок
- Как вы собираетесь волшебным образом импортировать вещи
- Какие плагины вы используете
- Ваш WebPack-Dev-Server Setup
- Как настроены ваши исходные карты.
Какие? Плагины? Исходные карты? Почему мне нужен другой сервер?
Плагины
Здесь мы просто используем плагин HotmoduleReaction (HMR). Это позволяет нашему браузеру автоматически перезагрузить, когда файл изменен. Это волшебно удаляет один шаг нормальной итерации записи, сохранения, тестирования.
Там есть тонны других плагинов – ( здесь Тот, который выделяется, но я не стал пытаться!)
Вот список популярных плагинов WebPack (почему WebPack делает так много вещей!)
Исходные карты
Исходные карты – это продукты ES6 и пакет. Я не разобрался, как получить их идеальным – есть несчастный компромисс скорости/качества, который возникает с SourceMaps, поскольку идеальные могут быть довольно медленными для создания. Наше преобразование ES6 достигается через Babel Loader.
Если мы оглядываемся на thecomponent.js
Это содержит большую часть нашего WebPack:
import template from './componentTemplate.html' import componentStylez from './componentStylez.sass' import {ComponentController} from './theComponentController.js' const bindings = { someInput: '<', someOutput: '&' } export const theComponent = { controller: ComponentController, template, bindings }
Обратите внимание, как мы импортируем HTML, SASS и ES6 здесь. Это достигается через наши погрузчики. Какой загрузчик используется, основан на имени файла.
Webpack-dev-сервер
WebPack-Dev-Server – это удивительная вещь, независимо от того, есть ли у вас настоящий задний конец. Он поддерживает HMR и является статическим файловым сервером, который делает ваше развитие быстрого. Кроме того, использование WebPack-dev-Server заставит вас сделать пару вашего интерфейса и заднего конца.
Возможность сделать разработку передней работы без необходимости «реального» сервера, потрясающе потрясает причины. Он заставит вас создавать практические данные издевательства, точно знать, какие функциональные возможности принадлежат к задней части против интерфейса, дайте вам HMR и сделать свой интерфейс Ходите по любому серверу, с четким договором между передней и задней частью.
В этой настройке WebPack-Dev-Server, наряду со всем остальным, необходимым для формирования передней части, выполняется одной командой WAP DEV NPM, как указано в Package.json
:
{ "name": "modern-angularjs-starter", "version": "0.0.1", "description": "Base project", "main": "index.js", "scripts": { "dev": "concurrently --kill-others \"webpack-dev-server --host 0.0.0.0\" \"npm run docs\"", "docs_gen": "jsdoc -r -d jsdoc_output/ public/", "docs_watch": "watch \"npm run docs_gen\" public", "docs_serve": "echo Docs are being served on port 8082! && live-server -q --port=8082 --no-browser jsdoc_output/", "docs": "concurrently --kill-others \"npm run docs_serve\" \"npm run docs_watch\"", "postinstall": "bower install", "webpack": "webpack", "test": "mocha-webpack public/**/*.spec.js" }, "devDependencies": { /* hidden for space */ } "dependencies": { /* hidden for space */ } }
Обратите внимание на использование одновременно Отказ
Это позволяет запускать 2 команды блокировки параллельно.
Обратите внимание, что есть также команды тестирования и документации. Команды документации генерируют страницы JSDOC, а затем проводят их на небольшом сервере, которые автоматически обновляются (аналогично HMR) браузером, когда есть изменение. Таким образом, вы можете наблюдать за вашими документами, когда вы пишете их, если вы сохраняете часто.
Это не продемонстрировано в этом проекте, однако указание типов в JSDOC является хорошим способом указать данные-контракты между передней/задней частью. В качестве альтернативы вы можете просто использовать TeampScript (для этого есть погрузчики).
Устройство тестирования (потому что это стоит усилий)
Тестирование с ES6 + Angularjs + WebPack Click, чтобы получить право. Каждое из этих вызывает осложнения. Для тестирования подразделения я оказался урегулирован на очень маленьких единицах, тестируя мои контроллеры Angularjs как функции в узле. Карма довольно популярна, но, на мой взгляд, тесты не на самом деле единичные тесты. Тем не менее, было бы полезно иметь оба.
Таким образом, у нас есть Mocha-WebPack Отказ Это позволяет нам использовать импорт в наших тестах, не указав выпускную точку для каждого.
Самая сложная часть о тестировании здесь издевается на импорт ES6. Есть несколько разных способов сделать это, но единственный, который не требует модификации тестируемого файла – INJECT-LOADER Отказ
Это особенно полезно для написания тестов, в которых издеваются вещи внутри вашего модуля-теста, иногда требуются перед выполнением – загрузчик ввода.
/* eslint-disable */ import chai from 'chai' import sinon from 'sinon' const theControllerInjector = require('inject-loader!./theComponentController.js') let {expect, should, assert} = chai describe('superAwesomeComponent', function() { let stub let theComponentController let controller beforeEach(function setupComponent () { stub = sinon.stub().returns(1) theComponentController = theControllerInjector({ // The module is really simple, so it's not really necessary to mock it // In a real app, it could be much more complex (ie, something that makes API calls) './fancyJsModule.js': stub }).ComponentController controller = new theComponentController() controller.someOutput = sinon.stub() controller.someInput = 1 }) describe('doSuperThings', function() { it('calls fancyFunction', function() { controller.doSuperThings() assert(stub.calledOnce) }) }) })
Чтобы использовать INJECT-LOADER, мы используем синтаксис загрузчика Wear End Tree + WebPack, потому что нет проверки файла filename подстановки, мы можем сделать для импорта (мы не хотим, чтобы все файлы JS пропущены в Inject Doader все время) Отказ Возвращение этого требует дает нам функцию, которую мы можем позвонить с объектом, опубшим различными импортами:
theComponentController = theControllerInjector({ './fancyJsModule.js': stub }).ComponentController
Здесь мы опубликовали Fancysmodule
Из импорта нашего контроллера. Это позволяет нам вернуть значение макияна, подкручивая всю логику, который может сделать модуль, поэтому мы можем изолировать любые проблемы, которые возникают в тесте.
Мы используем Чай Как наша учетная библиотека, Sinon.js Для издевания/шпионажа и Моча для работы тестов.
Этот тест не пытается быть хорошим примером того, что тестировать, просто показать, как тестирование можно настроить с ES6 + WebPack + Мока + угловой.
Целью этого является заставить разработчику сосредоточиться на написании обработчиков AngularJS в качестве фактических функций. Существует сильная тенденция для того, чтобы эти обработчики были выполнены исключительно для побочных эффектов, и создание этих испытаний выделит этот факт.
SOO …
Эта архитектура обеспечивает способ модернизации Angularjs Front-End, не делая рамки прыжка. Одним из самых больших преимуществ этого подхода является то, что это Изобретает много кода-специфического Angularjs.
Одним из самых сложных элементов этого подхода является решение того, что использовать модули Angularjs для против, для чего использовать модули ES6. Я стараюсь использовать ES6 как можно больше. Это должно облегчить порт приложения, используя эту архитектуру в другую структуру.
Angularjs по-прежнему оказывает свободное количество жизни, но нет никаких сомнений в том, что его прайм прошло. ES6/7, однако, все еще на подъем Отказ
Длинные живые Angularjs!
Кстати, проверьте мой Предыдущие РАНТ на JS
Этот пост был первоначально опубликован автором здесь Отказ Эта версия была отредактирована для ясности и может появиться отличаться от исходного поста.