গিটার সংগ্রহস্থলে "নোড_মডিউলস" ফোল্ডারটি অন্তর্ভুক্ত করা উচিত


176

আমি ভাবছি যদি আমাদের রেপোতে নোড_মডিউলগুলি ট্র্যাক করা উচিত বা কোডটি পরীক্ষা করার সময় এনপিএম ইনস্টল করা উচিত?


উত্তর:


177

উত্তরটি আলবার্তো জ্যাকাগনির পরামর্শ অনুসারে সহজ নয়। আপনার গিট রেপোতে নোড_মডিউলগুলি সহ আপনি যদি অ্যাপ্লিকেশনগুলি (বিশেষত এন্টারপ্রাইজ অ্যাপ্লিকেশনগুলি) বিকাশ করেন তবে এটি একটি কার্যকর বিকল্প এবং আপনি কোন বিকল্পটি চয়ন করেন তা আপনার প্রকল্পের উপর নির্ভর করে।

কারণ তিনি নোড_মডিউলগুলির বিরুদ্ধে খুব ভাল যুক্তি দিয়েছিলেন আমি তাদের পক্ষে যুক্তিতে মনোনিবেশ করব।

কল্পনা করুন যে আপনি সবেমাত্র এন্টারপ্রাইজ অ্যাপ্লিকেশনটি শেষ করেছেন এবং আপনাকে 3-5 বছর ধরে এটি সমর্থন করতে হবে। আপনি অবশ্যই কারও এনপিএম মডিউলের উপর নির্ভর করতে চান না যা আগামীকাল অদৃশ্য হয়ে যেতে পারে এবং আপনি আর আপনার অ্যাপ্লিকেশনটি আপডেট করতে পারবেন না।

অথবা আপনার ব্যক্তিগত ব্যক্তিগত মডিউল রয়েছে যা ইন্টারনেট থেকে অ্যাক্সেসযোগ্য নয় এবং আপনি আপনার অ্যাপ্লিকেশনটি ইন্টারনেটে তৈরি করতে পারবেন না। অথবা হতে পারে আপনি কোনও কারণে এনপিএম পরিষেবাতে আপনার চূড়ান্ত বিল্ডের উপর নির্ভর করতে চান না।

আপনি এই অ্যাডি ওসমানী নিবন্ধে ভাল এবং সন্ধান পেতে পারেন (যদিও এটি বোভার সম্পর্কে, এটি প্রায় একই পরিস্থিতি)। এবং আমি বোভার হোমপেজ এবং অ্যাডির নিবন্ধের একটি উদ্ধৃতি দিয়ে শেষ করব:

"আপনি যদি এমন প্যাকেজটি অনুমোদন করে না যা অন্যের দ্বারা গ্রাস করার উদ্দেশ্যে হয় (যেমন, আপনি একটি ওয়েব অ্যাপ বানাচ্ছেন), আপনার সর্বদা ইনস্টল করা প্যাকেজগুলি উত্স নিয়ন্ত্রণে পরীক্ষা করা উচিত” "


6
আমি এর সাথে পুরোপুরি একমত আমি চাই না যে আমাদের এন্টারপ্রাইজ বিল্ড সিস্টেমটিকে একটি সফল নির্মাণের জন্য একটি ইন্টারনেট সংযোগের প্রয়োজন, কারণ এটি নির্ভরতা ডাউনলোডের প্রয়োজন, যা আশাকরি এখনও রয়েছে। ধন্যবাদ।
4'13

9
@ অ্যালবার্তো জ্যাকাকানি আমাকে বিশ্বাস করে আপনি প্রথমবারের মতোই ছিলেন। আপনি যদি সত্যিই একটি এন্টারপ্রাইজ অ্যাপ তৈরি করে থাকেন তবে আপনার এন্টারপ্রাইজ সরঞ্জামগুলি ব্যবহার করা উচিত। ইন্টারনেট থেকে অদৃশ্য হওয়া প্রকল্পগুলির বিরুদ্ধে সুরক্ষার জন্য শৈল্পিক এবং এনপিএম-আর্টফ্যাক্টরি ব্যবহার করা উচিত। এমনকি ছোট প্রকল্পগুলিতে উত্স নিয়ন্ত্রণে একই জিনিসটির কয়েকটি অনুলিপি থাকার চেয়ে এটি পরিষ্কার।
টেড বিঘাম

10
পরে বাম-প্যাড ইস্যু , আমি মনে করি এটা স্পষ্টভাবে একটি খারাপ ধারণা node_modules ট্র্যাক করতে নয়।
লায়ো লাম

6
গুরুত্বপূর্ণ দিক নুন উল্লেখ করা। যদি আপনার নোড_মডিউলগুলি ভিসিএসের অধীনে থাকে - শাখাগুলি স্যুইচ করা ঠিক git checkout foo। যদি নোড_মডিউলগুলি ভিসিএসের আওতায় না থাকে - শাখাগুলি স্যুইচ করা হয় git checkout foo ; npm installএবং আপনার বর্তমান এনপিএম সংস্করণে কাজ করার জন্য যা কিছু প্রয়োজন;)
ইভান ক্লেশিনিন

7
সবচেয়ে পরিষ্কার উদ্যোগটি হ'ল কোনও অভ্যন্তরীণ ইন্ট্রানেট-অ্যাক্সেসযোগ্য এনপিএম সংগ্রহস্থল হোস্ট করা যা আপনার ব্যবহার করা সমস্ত মডিউলগুলির সংস্করণ রয়েছে এবং উত্স কোড সহ নোড_মডিউলগুলি পরীক্ষা করবেন না। আপনার বিল্ড সিস্টেমটি আপনার অভ্যন্তরীণ নোড সংগ্রহস্থলের উল্লেখ করবে।
ব্যবহারকারী 2867288

104

মডিউল বিশদ সংরক্ষণ করা হয় packages.json, যথেষ্ট। চেক ইন করার দরকার নেই node_modules

node_modulesমডিউলগুলির নির্ভরতা লক করতে লোকেরা সংস্করণ নিয়ন্ত্রণে সঞ্চয় করত , তবে এনপিএম সঙ্কুচিত দিয়ে এর আর দরকার নেই।

এই বিষয়টির জন্য আর একটি ন্যায়সঙ্গততা, যেমন ক্রিসিসএম মন্তব্যটিতে লিখেছেন:

এছাড়াও লক্ষণীয় যে, কোনও মডিউল যা দেশীয় এক্সটেনশানগুলিতে জড়িত সেগুলি আর্কিটেকচারের জন্য আর্কিটেকচারের কাজ করবে না এবং পুনর্নির্মাণের প্রয়োজন। এগুলি রেপোতে অন্তর্ভুক্ত না করার জন্য ন্যায্য ন্যায্যতা প্রদান।


10
সহজ, এবং বিন্দুতে +1। এছাড়াও লক্ষণীয় যে, কোনও মডিউল যা দেশীয় এক্সটেনশানগুলিতে জড়িত সেগুলি আর্কিটেকচারের জন্য আর্কিটেকচারের কাজ করবে না এবং পুনর্নির্মাণের প্রয়োজন। এগুলি রেপোতে অন্তর্ভুক্ত না করার জন্য ন্যায্য ন্যায্যতা প্রদান।
ChrisCM

3
সত্যই নয়, উদাহরণস্বরূপ, যোজনাগুলি দ্বারা পুনরুত্পাদনযোগ্য ডেভ পরিবেশ ব্যবহার করার পক্ষে এটি ন্যায়সঙ্গত। এটি কেবল একটি আর্কিটেকচারে কাজ করা উচিত।
রবিন স্মিথ

20

আমি উদাহরণস্বরূপ ফ্যানটমজেএস এবং নোড-স্যাসের মতো প্যাকেজগুলির কারণে নোড_মডিউলগুলি পরীক্ষা করার বিরুদ্ধে সুপারিশ করব , যা বর্তমান সিস্টেমের জন্য উপযুক্ত বাইনারি ইনস্টল করে।

এর অর্থ হ'ল যদি কোনও দেব npm installলিনাক্সে চালিত হন এবং নোড_মডিউলগুলি পরীক্ষা করেন - এটি অন্য কোনও দেবের পক্ষে কাজ করবে না যারা উইন্ডোজে রেপো ক্লোন করে।

যেসব টার্বলগুলি এনপিএম ডাউনলোডগুলি ইনস্টল করে সেগুলিতে নির্দেশ npm-shrinkwrap.jsonকরে তা পরীক্ষা করা ভাল । আপনি সঙ্কুচিত প্যাক ব্যবহার করে এই প্রক্রিয়াটি স্বয়ংক্রিয় করতে পারেন ।


তবে npm install --global shrinkpackনিজেই কি পিছিয়ে থাকা প্যাকেজগুলি ইনস্টল করতে হবে এমন অন্যান্য প্যাকেজগুলির প্রয়োজনের দ্বারা পিছিয়ে যাওয়া দুর্বলতা নেই? এটি অ্যাডির পরামর্শের বিরুদ্ধে যায়।
দানজাহ

আপনি প্রশ্নটি পুনরায় উত্তর দিতে পারেন দয়া করে @ উদ্যানজাহ? আমি আপনাকে পুরোপুরি বুঝতে পারছি না দুঃখিত।
জ্যামি ম্যাসন

আপনি যা বর্ণনা করেন তার উপর নির্ভরতা shrinkpack নির্ভরযোগ্যভাবে বিল্ড নির্ভরতা ইনস্টল করতে হবে। অতএব, বিল্ড সরঞ্জামের ইনস্টলেশন নিজেই সমস্ত বিল্ড নির্ভরতা সংস্করণ নিয়ন্ত্রণে জমা দেওয়ার বিরুদ্ধে যুক্তির দুর্বলতা হয়ে যায়।
ডানজাহ

1
আমি মনে করি লক ফাইলগুলিতে চেক করা যথেষ্ট (প্যাকেজ-লক.জসন; ইয়ার্ন.লক) কমপক্ষে টিএফএম অনুসারে: docs.npmjs.com/files/package-lock.json
আইমাস

1
লকফিল ব্যবহার করার সময় আপনি অনুমানযোগ্য নির্ভরতা গ্রাফ পাবেন এবং বিভিন্ন প্ল্যাটফর্মে ফ্যান্টমজেএস এবং নোড-স্যাস ইত্যাদির চারপাশে আলোচিত সমস্যাগুলির প্রতি সংবেদনশীল হবেন না। অবশ্যই আপনার অবশ্যই একটি ইন্টারনেট সংযোগ এবং নিবন্ধটি অবশ্যই অবশ্যই প্রস্তুত থাকতে হবে।
জেমি ম্যাসন

7

এই বিষয়টি বেশ পুরানো, আমি দেখছি। তবে এনপিএমের ইকো সিস্টেমে পরিবর্তিত পরিস্থিতির কারণে আমি এখানে সরবরাহিত যুক্তিগুলির কিছু আপডেট মিস করছি।

আমি সর্বদা সংস্করণ নিয়ন্ত্রণে নোড_মডিউল না রাখার পরামর্শ দেব। গৃহীত উত্তরের প্রসঙ্গে তালিকাভুক্ত হিসাবে এটি করা থেকে প্রায় সমস্ত সুবিধা এখন পর্যন্ত বেশ পুরানো।

  1. এনপিএম রেজিস্ট্রি থেকে আর সহজেই প্রকাশিত প্যাকেজগুলি বাতিল করা যাবে না। সুতরাং আপনার প্রকল্পের আগে নির্ভর করে থাকা নির্ভরতাগুলি হারাতে আপনাকে ভয় করতে হবে না।

  2. ভিসিএসে প্যাকেজ-জসন.লক ফাইল স্থাপন করা প্রায়শই আপডেট হওয়া নির্ভরতাগুলির সাথে সহায়তা করে সম্ভবত একই প্যাকেজ.জসন ফাইলের উপর নির্ভর করে যদিও বিভিন্ন সেটআপের ফলস্বরূপ।

সুতরাং, অফলাইন বিল্ড সরঞ্জাম থাকার ক্ষেত্রে নোড_মডিউলগুলি ভিসিএসে স্থাপন করা কেবলমাত্র যোগ্য ব্যবহারের কেস হিসাবে বিবেচিত হতে পারে। তবে নোড_মডিউলগুলি সাধারণত বেশ দ্রুত বৃদ্ধি পায় grows যে কোনও আপডেট অনেকগুলি ফাইল পরিবর্তন করবে। এবং এটি বিভিন্ন উপায়ে সংগ্রহস্থলগুলিকে প্রভাবিত করছে। আপনি যদি সত্যিই দীর্ঘমেয়াদী বিবেচনা করেন তবে এটিও একটি প্রতিবন্ধক হতে পারে।

সেন্ট্রালাইজড ভিসিএসের মতো 'এসএনএন'র জন্য নেটওয়ার্কের মাধ্যমে প্রতিশ্রুতিবদ্ধ এবং চেক আউট করা ফাইলগুলি স্থানান্তরিত করা দরকার যা নোড_মডিউল ফোল্ডারটি পরীক্ষা করে দেখার বা আপডেট করার ক্ষেত্রে নরকের মতো ধীর হতে চলেছে।

এই অতিরিক্ত সংখ্যক অতিরিক্ত ফাইলের গিটারটি যখন আসে তখন তাৎক্ষণিকভাবে সংগ্রহস্থলকে দূষিত করে। মনে রাখবেন যে গিট কোনও ফাইলের সংস্করণের মধ্যে পার্থক্য খুঁজে বের করছে না, তবে একক অক্ষর পরিবর্তনের সাথে সাথেই কোনও ফাইলের উভয় সংস্করণের অনুলিপি সংরক্ষণ করছে। যে কোনও নির্ভরতার প্রতিটি আপডেটের ফলে আরও একটি বৃহত্তর পরিবর্তন ঘটে। আপনার গিট সংগ্রহস্থলটি দ্রুত প্রভাব ফেলবে কারণ এটি ব্যাকআপ এবং রিমোট সিঙ্ক্রোনাইজেশনটিকে প্রভাবিত করে। আপনি যদি পরে গিট সংগ্রহস্থল থেকে নোড_মডিউলগুলি সরিয়ে ফেলার সিদ্ধান্ত নেন তবে এটি historicalতিহাসিক কারণে এখনও এটির অংশ। যদি আপনি কিছু কিছু রিমোট সার্ভারে আপনার গিট সংগ্রহস্থল বিতরণ করে থাকেন (যেমন ব্যাকআপের জন্য) এটি পরিষ্কার করা অন্য একটি বেদনাদায়ক এবং ত্রুটি-ঝুঁকির কাজ যা আপনি চালাচ্ছেন।

সুতরাং, যদি আপনি দক্ষ প্রক্রিয়াগুলির জন্য যত্নশীল হন এবং জিনিসগুলিকে "ছোট" রাখতে চান তবে আমি বরং পৃথক আর্টিফেক্ট রিপোজিটরি যেমন নেক্সোস রেপোজিটরি (অথবা জিপ সংরক্ষণাগার সহ কিছু HTTP সার্ভার) ব্যবহার করব, যা ডাউনলোডের জন্য পূর্বের কিছুটা নির্ভরশীলতার সেট সরবরাহ করে।


6

node_modulesসোর্স কন্ট্রোলের সাহায্যে ট্র্যাকিং করা সঠিক পছন্দ নয় কারণ কিছু নোডজেএস মডিউল যেমন মোংগোডিবি নোডজেএস ড্রাইভার নোডজেএস সি ++ অ্যাড-অন ব্যবহার করে। npm installকমান্ড চলাকালীন এই অ্যাড-অনগুলি সংকলিত হয় । সুতরাং যখন আপনি node_modulesডিরেক্টরি ট্র্যাক করেন , আপনি দুর্ঘটনাক্রমে কোনও ওএস নির্দিষ্ট বাইনারি ফাইল প্রতিশ্রুতিবদ্ধ করতে পারেন।


3

আমি ivoszz এর সাথে একমত যে নোড_মডিউলগুলি ফোল্ডারটি পরীক্ষা করতে এটি কখনও কখনও দরকারী তবে ...


দৃশ্যপট 1:

একটি দৃশ্য: আপনি এমন একটি প্যাকেজ ব্যবহার করেন যা এনপিএম থেকে সরানো হয়। নোড_মডিউলগুলি ফোল্ডারে যদি আপনার সমস্ত মডিউল থাকে তবে তা আপনার পক্ষে সমস্যা হবে না। আপনার যদি কেবল প্যাকেজ.জসনে প্যাকেজের নাম থাকে তবে আপনি এটি আর পেতে পারবেন না। যদি কোনও প্যাকেজ 24 ঘন্টােরও কম পুরানো হয় তবে আপনি সহজেই এনপিএম থেকে সরাতে পারেন। যদি এটি 24 ঘন্টা পুরানো হয় তবে আপনার তাদের সাথে যোগাযোগ করা দরকার। কিন্তু:

আপনি যদি সহায়তার সাথে যোগাযোগ করেন তবে তারা আপনার প্যাকেজের সেই সংস্করণটি অপসারণ করা অন্য কোনও ইনস্টল ভেঙে ফেলবে কিনা তা পরীক্ষা করে দেখবে। যদি তা হয় তবে আমরা এটি সরাব না।

আরও পড়ুন

সুতরাং এর সম্ভাবনা কম, তবে দৃশ্যপট 2 রয়েছে ...


দৃশ্য 2:

অন্য পরিস্থিতি যেখানে এটি হয়: আপনি আপনার সফ্টওয়্যারটির একটি এন্টারপ্রাইজ সংস্করণ বা একটি খুব গুরুত্বপূর্ণ সফ্টওয়্যার বিকাশ করুন এবং আপনার প্যাকেজ.জসনে লিখুন:

"dependencies": {
    "studpid-package": "~1.0.1"
}

আপনি function1(x)এই প্যাকেজটির পদ্ধতিটি ব্যবহার করেন ।

এখন studpid-প্যাকেজের ডেভেলপারদের পদ্ধতি নামান্তর function1(x)করতে function2(x)পারেন এবং তারা একটি ফল্ট করুন ... তারা থেকে তাদের প্যাকেজের সংস্করণ পরিবর্তন 1.0.1করতে 1.1.0। এটি একটি সমস্যা কারণ আপনি যখন npm installপরের বার কল করবেন তখন আপনি সংস্করণ গ্রহণ করবেন1.1.0 কারণ আপনি টিলড ( "studpid-package": "~1.0.1") ব্যবহার করেছেন ।

কল করা হচ্ছে function1(x) ফলে এখন ত্রুটি ও সমস্যা দেখা দিতে পারে।


কিন্তু:

পুরো নোড_মডিউলগুলি ফোল্ডারটি (প্রায়শই 100 এমবি এর বেশি) আপনার সংগ্রহস্থলে পুশ করা আপনার মেমরির জায়গার জন্য ব্যয় করে। কয়েক কেবি (প্যাকেজ.জসন) কয়েকশ এমবি (প্যাকেজ.জসন এবং নোড_মডিউলস) এর সাথে তুলনা করে ... এটি সম্পর্কে চিন্তা করুন।

আপনি এটি করতে পারেন / এটি সম্পর্কে চিন্তা করা উচিত যদি:

  • সফ্টওয়্যারটি খুব গুরুত্বপূর্ণ।

  • কিছু ব্যর্থ হলে এটি আপনার অর্থ ব্যয় করে।

  • আপনি এনপিএম রেজিস্ট্রি বিশ্বাস করেন না। এনপিএমটি কেন্দ্রিয়ায়িত এবং তাত্ত্বিকভাবে বন্ধ হয়ে যেতে পারে।

আপনি প্রয়োজন হবে না ক্ষেত্রেই যদি এর 99.9% ফোল্ডার node_modules প্রকাশ করতে:

  • আপনি কেবল নিজের জন্য একটি সফ্টওয়্যার বিকাশ করুন।

  • আপনি কিছু প্রোগ্রাম করেছেন এবং ফলাফলটি কেবল গিটহাবের উপরে প্রকাশ করতে চান কারণ অন্য কেউ হয়তো এতে আগ্রহী হতে পারেন।


আপনি যদি চান না যে নোড_মডিউলগুলি আপনার ভান্ডারে থাকতে পারে তবে কেবল একটি .gitignoreফাইল তৈরি করুন এবং লাইনটি যুক্ত করুন node_modules


1
"নোড_মডিউলগুলি ফোল্ডার প্রকাশের" এর আরও একটি অসুবিধা হতে পারে: npm installউইন্ডোজ এবং ম্যাকোএসে কল করা কিছু প্যাকেজে বিভিন্ন ফাইল (ওএস-নির্ভর ফাইল) তৈরি করতে পারে। তবে আমি সে সম্পর্কে নিশ্চিত নই। কেউ সত্য যাচাই করতে পারে?
ndvww

2
"পরিস্থিতি 2": এজন্য আপনি প্রতিশ্রুতিবদ্ধ package-lock.json। ভবিষ্যতে স্টাডিপিড-প্যাকেজ আপডেটে সমস্যা থাকলে, আপনার জন্য সঠিক সংস্করণটি কার্যকর হয়েছিল তা খুঁজে পেতে আপনি লক ফাইলটি আবার রোল করতে পারেন।
টুলমেকারস্টেভ

2

আমি রাস্তার বিকল্পের মাঝখানে অফার করতে চাই।

  1. node_modulesগিট মধ্যে যোগ করবেন না ।
  2. package-lock.jsonআপনার নির্ভরতা সংস্করণ পেরেক করতে একটি ফাইল ব্যবহার করুন ।
  3. আপনার সিআই বা রিলিজ প্রক্রিয়ায় আপনি যখন সংস্করণ প্রকাশ করেন তখন নোড_মডিউলগুলি ফোল্ডারের একটি অনুলিপি তৈরি করুন এবং এটি ব্যাক আপ করুন (যেমন মেঘ স্টোরেজে)।

বিরল ইভেন্টে আপনি এনপিএম (বা আপনি যে অন্যান্য রেজিস্ট্রেশনগুলি ব্যবহার করেন) বা এনপিএমের একটি নির্দিষ্ট প্যাকেজ অ্যাক্সেস করতে পারবেন না, আপনার নোড_মডিউলগুলির একটি অনুলিপি রয়েছে এবং আপনি অ্যাক্সেস পুনরুদ্ধার না করা পর্যন্ত কাজ চালিয়ে যেতে পারেন।


0

আরও একটি বিষয় বিবেচনা করুন: চেক ইন করা এবং এর node_modulesমধ্যে পার্থক্যটি ব্যবহার করা শক্ত / অসম্ভব করে তোলেdependenciesdevDependencies

অন্যদিকে, কেউ বলতে পারে যে পরীক্ষার মধ্য দিয়ে গেছে সেই একই কোডটি উত্পাদনের দিকে ঠেলে দেওয়া আশ্বাস দেয় devDependencies। সুতরাং অন্তর্ভুক্ত ।


"পরীক্ষাগুলির মধ্য দিয়ে আসা একই কোডটি তৈরি করতে": আপনার কাছে ডকার এটিই। অথবা কোনও ওএস প্যাকেজ ম্যানেজার, আরপিএমের মতো। আপনি টেস্ট এবং প্রোডের মধ্যে কোডটি পুনর্নির্মাণ করেন না, তাই না? ডেভিনিডেন্সিগুলি চূড়ান্ত কোডটি তৈরি করতে সহায়তা করেছিল, তবে কোনও স্থাপনার কোনও জায়গা নেই, পরীক্ষা বা প্রোডও নয়।
প্রতি উইকল্যান্ডের

যদি ডিডিডিপেন্ডেনসগুলি তাদের নিজস্ব প্যাকেজে থাকে তবে এটি কী সহায়তা করবে? জেসন "এসসিআর" ডিরেক্টরি থেকে একটি ডিরেক্টরি উচ্চতর? যেহেতু নোড মডিউলগুলি বর্তমান ডিরেক্টরিতে শুরু করার জন্য অনুসন্ধান করা হচ্ছে এবং তারপরে উপরের দিকে এগিয়ে চলেছে, তবুও আপনার ডেভ নির্ভরতা ব্যবহার করা উচিত এবং ডেভ / এসসিআর মডিউলগুলির পৃথককরণ হওয়া উচিত।
অ্যালেক্স

0

প্যাকেজ.জসনে নির্ভরতা উল্লেখ করা থাকলে নোড_মডিউলগুলি চেক-ইন করার প্রয়োজন হয় না। অন্য কোনও প্রোগ্রামার সহজেই এনপিএম ইনস্টল করে তা পেতে পারে এবং এনপিএম আপনার পক্ষে প্রকল্পের জন্য ওয়ার্কিং ডিরেক্টরিতে নোড_মডিউলগুলি তৈরি করতে যথেষ্ট স্মার্ট।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.