دليل المبتدئين لـ Node.js الجزء 3





يوم جيد يا اصدقاء!



ما زلت للنشر ترجمة لهذا البرنامج التعليمي نود.جي إس .



الأجزاء الأخرى:



الجزء الأول

الجزء الثاني

الجزء الثالث

الجزء الرابع



إحضار المستخدم لإدخال البيانات في Node.js



كيف أجعل برنامج Node.js تفاعليًا؟



للقيام بذلك، الإصدار 7 من نود.جي إس يدخل يقوم readline حدة : يتم استخدامه للحصول على بيانات من تيار لقراءة مثل process.stdin- سطر الأوامر أثناء تنفيذ برنامج نود.جي إس.



const readline = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
})

readline.question(`What is your name?`, name => {
    console.log(`Hi ${name}!`)
    readline.close()
})


يطلب هذا الرمز اسم المستخدم ، بعد كتابة المستخدم والنقر enter، يتم عرض رسالة ترحيب.



تقوم الطريقة question()بطباعة المعلمة الأولى (السؤال) إلى وحدة التحكم وتنتظر استجابة المستخدم. عند الضغط عليه enter، يتم تنفيذ وظيفة رد الاتصال.



في رد الاتصال هذا ، نغلق الواجهة readline.



readlineيحتوي على طرق أخرى ، يمكنك أن تقرأ عنها في الوثائق.



إذا كنت بحاجة إلى المطالبة بكلمة مرور ، فمن الأفضل عدم إعادتها بشكل صريح ، بل استخدام الرموز *.



تتمثل إحدى طرق القيام بذلك في استخدام حزمة مزامنة خط القراءة ، وهي سهلة الفهم وسهلة التهيئة.



يتم توفير حل أكثر اكتمالا وتجريد من خلال حزمة Inquirer.js .



نقوم بتثبيته بمساعدة npm install inquirerونستخدمه على النحو التالي:



const inquirer = require('inquirer')

const questions = [
    {
        type: 'input',
        name: 'name',
        message: `What's your name?`
    }
]

inquirer.prompt(questions).then(answers => {
    console.log(`Hi ${answers['name']}!`)
})


يتيح لك Inquirer.js القيام بالكثير من الأشياء الرائعة ، مثل اقتراح خيارات متعددة ، وتوفير أزرار الراديو ، وطلب التأكيد ، وما إلى ذلك.



يُعرف بشكل أفضل كبديل للحلول المضمنة ، ولكن إذا كنت تخطط لنقل تجربة المستخدم إلى المستوى التالي ، فإن Inquirer.js هو الحل الأفضل.



توسيع وظائف ملف Node.js باستخدام التصدير



يحتوي Node.js على نظام معياري مضمن.



يمكن لملف Node.js استيراد وظائف من ملفات Node.js أخرى.



عندما تريد استيراد شيء تستخدمه const library = require('./library')

لاستيراد وظائف تم تصديرها في ملف library.jsموجود في الدليل الحالي.



في هذا الملف ، يجب تصدير الوظائف قبل استيرادها في ملف آخر.



أي كائن أو متغير آخر محدد في ملف يكون افتراضيًا خاصًا (خاصًا) ولا يمكن استخدامه في ملفات أخرى.



هذا ما تسمح لنا الواجهة module.exportsالتي يوفرها النظام المعياري بالقيام بذلك .



عندما تقوم بتعيين كائن أو وظيفة كخاصية جديدة للكائنexports، تقوم بتصديرها ، ومن ثم يمكن استيرادها في مكان آخر في التطبيق أو في تطبيق آخر.



ويمكن أن يتم ذلك بطريقتين.



الطريقة الأولى هي تعيين قيمة module.exports، وهي الكائن الافتراضي الذي يوفره النظام المعياري. تسمح لك هذه الطريقة بتصدير هذا الكائن فقط:



const car = {
    brand: 'Ford',
    model: 'Fiesta'
}

module.exports = car 

//   
const car = require('./car')


الطريقة الثانية هي إضافة الكائن المُصدّر كخاصية للكائن exports. تسمح لك هذه الطريقة بتصدير العديد من الكائنات أو الوظائف أو البيانات:



const car = {
    brand: 'Ford',
    model: 'Fiesta'
}

exports.car = car


أو هكذا



exports.car = {
    brand: 'Ford',
    model: 'Fiesta'
}


لاستخدام هذا الكائن في ملف آخر ، يجب عليك إنشاء ارتباط للاستيراد:



const items = require('./items')
items.car 


أو



const car = require('./items').car 


ما الفرق بين module.exportsو exports؟



يقوم الأول بتصدير الكائن المشار إليه ، والثاني خاصية للكائن.



مقدمة لمدير حزمة npm



مقدمة عن npm


npmهو مدير الحزم Node.js الافتراضي.



اعتبارًا من كانون الثاني (يناير) 2017 ، كان لدى npm أكثر من 350.000 حزمة ، مما يجعلها أكبر مستودع للتعليمات البرمجية بلغة برمجة واحدة على وجه الأرض ، ويمكنك الاطمئنان إلى وجود حزم لأي شيء تقريبًا.



بدأ كل شيء مع تنزيل التبعيات وإدارتها في Node.js ، ولكن سرعان ما بدأ استخدام هذه الأداة بنشاط في تطوير جانب العميل من التطبيقات.



npmيقوم بعدة أشياء.



بديل ل npm هو الغزل .



جار التحميل


npmيدير تحميل تبعيات المشروع.



إذا كان الملف موجودًا في المشروع ، package.jsonفسيعمل الإطلاق npm installعلى تثبيت كل ما يتطلبه المشروع في الدليل node_modulesالذي تم إنشاؤه إذا لم يكن موجودًا.



يمكن تثبيت حزمة معينة باستخدام npm install <package-name>.



غالبًا ما يكون تركيب الحزمة مصحوبًا بأعلام:



  • --حفظ - قم بتثبيت الحزمة وإضافة إدخال حولها إلى قسم التبعيات في الملف package.json
  • - حفظ-ديف - تثبيت الحزمة وإضافة إدخال حولها إلى قسم devDependencies من الملف package.json


والفرق الرئيسي هو أنه يتم استخدام devDependence لأغراض التطوير ، على سبيل المثال ، للاختبار ، ويتم استخدام التبعيات في الإنتاج (عند بناء مشروع).



تحديث الحزم


التحديث سهل مع npm update.



npmسيتحقق من جميع الحزم للإصدارات الجديدة التي تلبي القيود الموضوعة.



يمكنك أيضا تحديث حزمة محددة: npm update <package-name>.



تعيين الإصدار


بالإضافة إلى التنزيلات القياسية ، يدعم npm الإصدار ، بحيث يمكنك تحديد أي إصدار محدد من الحزمة ، أو طلب إصدار أحدث أو أقدم.



ستجد غالبًا أن مكتبة واحدة متوافقة فقط مع إصدار معين (رئيسي) من مكتبة أخرى.



وأيضًا مع أخطاء أحدث الإصدارات التي لم يتم إصلاحها لفترة طويلة.



يساعد الإصدار أيضًا في تطوير الفريق لأن كل عضو في الفريق يعرف الإصدار الذي يجب استخدامه قبل تحديث الملف package.json.



في جميع هذه الحالات ، يساعد الإصدار ؛ في هذا الصدد ، npmفإنه يتبع المعايير المقبولة.



تنفيذ المهام


package.jsonيدعم صيغة لتحديد الأوامر التي سيتم تنفيذها في النهاية الطرفية مع npm run <task-name>.



فمثلا:



{
    "scripts": {
        "start-dev": "node lib/server-development",
        "start": "node lib/server-production"
    },
}


من الممارسات الشائعة استخدام هذه الإمكانية لتشغيل Webpack:

{
    "scripts": {
        "watch": "webpack --watch --progress --colors --config webpack.conf.js",
        "dev": "webpack --progress --colors --config webpack.conf.js",
        "prod": "NODE_ENV=production webpack -p --config webpack.conf.js"
    },
}


وهذا يسمح ، بدلاً من مجموعة من الأوامر الطويلة التي يسهل نسيانها أو التي يسهل ارتكابها ، بالقيام بذلك:



npm run watch 
npm run dev 
npm run prod 




أين يقوم npm بتثبيت الحزم؟



عند تثبيت الحزم باستخدام ، npmيمكنك الاختيار بين نوعين من التثبيت:



  • محلي
  • عالمي


بشكل افتراضي ، عندما تدخل npm installعلى سبيل المثال:



npm install lodash 


يتم تثبيت الحزمة على مجلد node_modulesفي الدليل الحالي.



بعد التثبيت npmيضيف سجل س lodashلقسم dependenciesالملف package.jsonفي الدليل الحالي.



للتثبيت العام ، استخدم العلم -g:



npm install -g lodash 


في التثبيت العام ، لا يتم تثبيت الحزمة في الدليل الحالي ، ولكن في الدليل العام.



لكن أين بالضبط؟



لتحديد ذلك ، تحتاج إلى تشغيل الأمر npm root -g.



على macOS أو Linux ، يمكن أن يكون هذا الدليل /usr/local/lib/node_modules. على نظام التشغيل Windows - C:\Users\YOU\AppData\Roaming\npm\node_modules. قد يختلف هذا الدليل



عند استخدامه nvmلإصدارات Node.js.



كيف أستخدم الحزم المثبتة؟



كيفية استخدام node_modulesحزمة مثبتة في مجلد أو عالميًا.



لنفترض أنك قمت بتثبيت lodashمكتبة مساعد JavaScript شائعة باستخدام npm install lodash.



سيتم تثبيت هذا الأمر lodashعلى دليل محلي node_modules.



لاستخدام البرنامج ، تحتاج إلى استيراد الحزمة باستخدام require:



const _ = require('lodash')


ماذا لو كانت الحزمة قابلة للتنفيذ (ملف)؟



في هذه الحالة ، سيتم وضع الملف القابل للتنفيذ في الدليل node_modules/.bin/.



يمكن إثبات ذلك بسهولة باستخدام مكتبة cowsay .



توفر هذه الحزمة برنامج سطر الأوامر ، عندما يتم تنفيذها ، فإن البقرة (والحيوانات الأخرى) "تتحدث" عن شيء ما.



عند تثبيت حزمة عبر npm install cowsay، سيتم تثبيت الحزمة نفسها والعديد من تبعياتها:







المجلد .binمخفي ويحتوي على ارتباطات رمزية إلى cowsay البيانات الثنائية:







كيفية تنفيذها؟



يمكنك بالطبع الكتابة ./node_modules/.bin/cowsayويجب أن تعمل ، ولكن npx المضمنة مع npm (منذ 5.2) هو الخيار الأفضل. فقط افعلهاnpx cowsayوسيحدد npx الملف تلقائيًا:





تقول البقرة "أخرجني من هنا".



دليل Package.json



عند العمل مع JavaScript ، عند التفاعل مع مشروع JavaScript ، أو Node.js ، أو الواجهة الأمامية لتطبيق ما ، من المحتمل أن تصادفك package.json.



ما هذا؟ ماذا يجب ان تعرف عنه؟ وماذا يمكنك أن تفعل به؟



package.jsonهو نوع من بيان المشروع. يمكنه أن يفعل أشياء كثيرة لا علاقة لها ببعضها البعض. على سبيل المثال ، يمكن أن يكون الملف الرئيسي لإعدادات الأدوات المستخدمة. يقوم أيضًا بتخزين أسماء وإصدارات جميع الحزم المثبتة (يتم استخدام هذه المعلومات npmو yarn).



هيكل الملف


إليك مثال package.json:



{}


كما ترون ، إنها فارغة. لا package.jsonتوجد متطلبات للمحتوى . الشرط الوحيد هو تنسيقه (JSON) ، وإلا فلن تتمكن البرامج من الوصول إليه.



إذا كنت تقوم بإنشاء حزمة Node.js التي تخطط للتوزيع من خلالها npm، فإن الوضع يتغير بشكل كبير وتحتاج إلى إضافة خصائص لمساعدة الآخرين على استخدام الحزمة. سننظر في هذا لاحقًا.



إليك مثال آخر package.json:



"name": "test-project"


قمنا هنا بتحديد اسم الحزمة أو التطبيق الموجود في نفس الدليل package.json.



فيما يلي مثال لمثال أكثر تعقيدًا تم package.jsonاستعارته من تطبيق Vue.js:



{
  "name": "test-project",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "main": "src/main.js",
  "private": true,
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "unit": "jest --config test/unit/jest.conf.js --coverage",
    "test": "npm run unit",
    "lint": "eslint --ext .js,.vue src test/unit",
    "build": "node build/build.js"
  },
  "dependencies": {
    "vue": "^2.5.2"
  },
  "devDependencies": {
    "autoprefixer": "^7.1.2",
    "babel-core": "^6.22.1",
    "babel-eslint": "^8.2.1",
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
    "babel-jest": "^21.0.2",
    "babel-loader": "^7.1.1",
    "babel-plugin-dynamic-import-node": "^1.2.0",
    "babel-plugin-syntax-jsx": "^6.18.0",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-plugin-transform-vue-jsx": "^3.5.0",
    "babel-preset-env": "^1.3.2",
    "babel-preset-stage-2": "^6.22.0",
    "chalk": "^2.0.1",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.28.0",
    "eslint": "^4.15.0",
    "eslint-config-airbnb-base": "^11.3.0",
    "eslint-friendly-formatter": "^3.0.0",
    "eslint-import-resolver-webpack": "^0.8.3",
    "eslint-loader": "^1.7.1",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-vue": "^4.0.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^1.1.4",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "html-webpack-plugin": "^2.30.1",
    "jest": "^22.0.4",
    "jest-serializer-vue": "^0.3.0",
    "node-notifier": "^5.1.2",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.8",
    "postcss-url": "^7.2.1",
    "rimraf": "^2.6.0",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "uglifyjs-webpack-plugin": "^1.1.1",
    "url-loader": "^0.5.8",
    "vue-jest": "^1.0.2",
    "vue-loader": "^13.3.0",
    "vue-style-loader": "^3.0.1",
    "vue-template-compiler": "^2.5.2",
    "webpack": "^3.6.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
  },
  "engines": {
    "node": ">= 6.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": ["> 1%", "last 2 versions", "not ie <= 8"]
}


هناك الكثير هنا:



  • name - اسم التطبيق / الحزمة
  • version - إصدار التطبيق / الحزمة
  • description - وصف موجز للتطبيق / الحزمة
  • main - الملف الرئيسي (نقطة الدخول) للتطبيق
  • private- القيمة trueتمنع النشر العرضي للتطبيقnpm
  • scripts - مجموعة من البرامج النصية (الأوامر) التي يمكن تشغيلها (تنفيذها)
  • dependencies - تبعيات المشروع
  • devDependencies - تبعيات المشروع تستخدم فقط أثناء التطوير
  • engines - الإصدارات التي يعمل عليها التطبيق / الحزمة
  • browserlist - المتصفحات المدعومة (وإصداراتها)


يتم استخدام جميع هذه الخصائص npm.



الخصائص


في هذا القسم ، سنتحدث عن بعض الخصائص التي يمكنك استخدامها. سنستخدم مصطلح "الحزمة" ، ولكن معظم ما قيل ينطبق أيضًا على التطبيقات.



هناك حاجة إلى معظم الخصائص لنشر الحزمة على npmبعضها للتفاعل مع الحزمة.



اسم اسم)


يحدد اسم الحزمة.



فمثلا:



"name": "test-project"


يجب ألا يتجاوز الاسم 214 حرفًا ، ويجب ألا يحتوي على مسافات ، وقد يتكون فقط من أحرف صغيرة (صغيرة) وواصلات (-) وشرطة سفلية (_).



وذلك لأنه npmيتم تعيين عنوان URL للحزمة عندما يتم نشره بناءً على اسمه.



إذا تم نشر الحزمة على GitHub ، فمن الأفضل الارتباط بالمخزن.



مؤلف


يحدد مؤلف الحزمة.



فمثلا:



{
    "author": "Joe <joe@whatever.com> (https://whatever.com)"
}


او مثل هذا:



{
  "author": {
    "name": "Joe",
    "email": "joe@whatever.com",
    "url": "https://whatever.com"
  }
}


المساهمون


يحدد مساهمًا واحدًا أو أكثر في الحزمة. هذه الخاصية هي مجموعة من السلاسل.



فمثلا:



{
  "contributors": ["Joe <joe@whatever.com> (https://whatever.com)"]
}


او مثل هذا:



{
  "contributors": [
    {
      "name": "Joe",
      "email": "joe@whatever.com",
      "url": "https://whatever.com"
    }
  ]
}


أخطاء


يحدد رابطًا لمتتبع المشكلات ، وعادة ما يكون متتبعًا للمشكلات على GitHub.



فمثلا:



{
  "bugs": "https://github.com/whatever/package/issues"
}


الصفحة الرئيسية


يحدد عنوان الصفحة الرئيسية.



فمثلا:



{
  "homepage": "https://whatever.com/package"
}


الإصدار


يحدد الإصدار الحالي من الحزمة.



فمثلا:



"version": "1.0.0"


تتبع هذه الخاصية معيار الإصدار الدلالي. هذا يعني أنه يجب أن يتكون دائمًا من ثلاثة أرقام مفصولة بنقاط x.x.x.



الرقم الأول هو الإصدار الرئيسي ، والثاني هو الإصدار الثانوي ، والثالث هو التصحيح.



كل رقم له معنى محدد: تحديث لإصلاح الأخطاء هو تصحيح ، وإصدار التغييرات المتوافقة مع الإصدارات السابقة هو إصدار ثانوي ، وقد يعني الإصدار الرئيسي تغييرات غير متوافقة مع الإصدار السابق.



رخصة


يحدد ترخيص الحزمة.



فمثلا:



"license": "MIT"


الكلمات الدالة


هذه الخاصية عبارة عن مجموعة من الكلمات الأساسية المرتبطة بالحزمة.



فمثلا:



"keywords": [
  "email",
  "machine learning",
  "ai"
]


يساعدون الناس في العثور على الحزم.



وصف


يحدد وصفا مختصرا للحزمة.



فمثلا:



"description": "A package to work with strings"


عند نشر حزمة على npmخاصية معينة ، فإنه يساعد الناس على فهم الغرض منها.



مخزن


يحدد مكان وجود الكود المصدري للحزمة.



فمثلا:



"repository": "github:whatever/testing",


انتبه إلى البادئة github. هناك خدمات أخرى مماثلة:



"repository": "gitlab:whatever/testing",


"repository": "bitbucket:whatever/testing",


يمكنك أيضًا تحديد نظام التحكم في الإصدار:



"repository": {
  "type": "git",
  "url": "https://github.com/whatever/testing.git"
}


يمكنك تحديد أنظمة تحكم إصدار متعددة:



"repository": {
  "type": "svn",
  "url": "..."
}


الأساسية


يحدد الملف الرئيسي (نقطة الدخول) للحزمة.



عند استيراد حزمة إلى تطبيق ، سيبحث التطبيق في هذا الملف عن الوحدات النمطية المصدرة.



فمثلا:



"main": "src/main.js"


نشر


يؤدي تعيين هذه الخاصية إلى قيمة إلى trueمنع نشر الحزمة عن طريق الخطأ إلى npm.



فمثلا:



"private": true 


نصوص


يحدد قائمة بالأوامر (البرامج النصية) التي يمكن تنفيذها (تشغيل).



فمثلا:



"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "start": "npm run dev",
  "unit": "jest --config test/unit/jest.conf.js --coverage",
  "test": "npm run unit",
  "lint": "eslint --ext .js,.vue src test/unit",
  "build": "node build/build.js"
}


هذه البرامج النصية هي تطبيقات سطر الأوامر. يمكنك تشغيلها باستخدام ، npm run XXXXأو yarn run XXXXأين XXXXهو اسم الأمر. على سبيل المثال: npm run dev.



يمكنك استخدام أي اسم كاسم الأمر ، سيقوم البرنامج النصي بكل ما تحدده فيه.



التبعيات


يحدد قائمة تبعيات الحزمة.



عند تثبيت حزمة باستخدام npm أو الغزل:



npm install <PACKAGENAME>
yarn add <PACKAGENAME>


ستتم إضافة السجل الخاص بهذه الحزمة تلقائيًا إلى الخاصية المعنية.



فمثلا:



"dependencies": {
  "vue": "^2.5.2"
}


devDependencies


يحدد قائمة التبعيات لأغراض التطوير.



وهي تختلف عن dependenciesأنها مثبتة فقط على كمبيوتر المطور ولا تدخل في الإنتاج.



عند تثبيت حزمة باستخدام npm أو الغزل:



npm install --save-dev <PACKAGENAME>
yarn add --save-dev <PACKAGENAME>


تتم إضافة السجل الخاص به تلقائيًا إلى الخاصية التي تم النظر فيها.



فمثلا:



"devDependencies": {
  "autoprefixer": "^7.1.2",
  "babel-core": "^6.22.1"
}


المحركات


يحدد إصدارات Node.js أو أدوات أخرى تعمل الحزمة / التطبيق عليها.



فمثلا:



"engines": {
  "node": ">= 6.0.0",
  "npm": ">= 3.0.0",
  "yarn": "^0.13.0"
}  


قائمة المتصفح


يحدد قائمة بالمتصفحات المدعومة (وإصداراتها). يتم استخدام هذه المعلومات بواسطة Babel و Autoprefixer وأدوات أخرى لإنشاء ملفات متعددة وضمان التوافق مع المتصفحات المحددة.



فمثلا:



"browserslist": [
  "> 1%",
  "last 2 versions",
  "not ie <= 8"
]    


يعني هذا الإعداد أنك تريد دعم أحدث إصدارين من جميع المتصفحات التي يستخدمها أكثر من 1٪ من الأشخاص وفقًا لإحصائيات CanIUse ، باستثناء IE8 والإصدارات الأقدم.



خصائص خاصة


package.jsonيمكن أن تحتوي على خصائص خاصة لأدوات مثل Babel و ESLint وما إلى ذلك.



كل من هذه الأدوات لها خصائصها الخاصة ، على سبيل المثال eslintConfig، babelوهلم جرا. للحصول على تفاصيل حول الخصائص الخاصة ، راجع الوثائق المقابلة.



إصدارات الحزمة


في الأمثلة أعلاه ، ربما لاحظت إدخالات مثل هذا: ~3.0.0، ^0.13.0. ماذا يقصدون؟ وما محددات الإصدارات الأخرى التي يمكنني استخدامها؟



يتم استخدام هذه المحددات لتحديد شروط التحديث.



قواعد هي على النحو التالي:



  • ~- ~0.13.0تعني الكتابة أنه لا يُسمح إلا بتحديثات التصحيح ، أي الإصدار 0.13.1صالح ، لكن الإصدار 0.14.0ليس كذلك
  • ^- الكتابة ^0.13.0تعني السماح بالتصحيحات والتحديثات الطفيفة
  • *- *يعني التسجيل أن أي تحديثات مسموح بها
  • > - يسمح بأي إصدارات جديدة
  • >= - يسمح بإصدارات مماثلة أو أحدث
  • <= - إصدارات مماثلة أو أقدم مقبولة
  • < - يسمح بأي إصدارات قديمة


إليك بعض القواعد الأخرى:



  • لا يوجد حرف بادئة - يُسمح فقط بالإصدار المحدد
  • latest - يسمح فقط بأحدث إصدار


هذه الشخصيات يمكن الجمع بين بطرق مختلفة، على سبيل المثال: 1.0.0 || >=1.1.0 <1.2.0.



شكرا لك على الاهتمام.



يتبع…



All Articles